动态代理模式
动态代理是 Java 反射(Reflection)API 提供的一种强大机制,它允许在运行时创建对象的代理实例,而不需要在编译时静态地创建。
Java 提供了两种主要的方式来实现动态代理:
- 基于接口的动态代理:使用
java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。 - 基于类的动态代理:通常使用第三方库如 CGLIB(Code Generation Library)。
如何实现动态代理
-
定义接口:首先,需要一个或多个接口,这些接口定义了代理对象需要实现的方法。
-
实现 InvocationHandler:创建一个实现了
InvocationHandler接口的类。这个类的invoke方法会在代理对象的每个方法被调用时执行。 -
创建代理实例:使用
Proxy.newProxyInstance方法(也可以其他方式创建代理实例)在运行时动态创建代理对象。这个方法接收三个参数:- 一个
ClassLoader,用于定义代理类; - 一个接口数组,指定代理对象需要实现的接口;
- 一个
InvocationHandler实例,用于处理代理对象的方法调用。
- 一个
-
调用代理方法:当代理对象的方法被调用时,
invoke方法会被触发,你可以在这个方法中添加自定义逻辑,如日志记录、权限检查等。 -
执行目标方法:在
invoke方法内部,可以通过反射调用实际对象的方法。如果有需要,还可以在调用前后添加额外的逻辑。
源码案例解读
在Mybatis框架中的MapperProxy类,就使用了动态代理技术。它首先实现了InvocationHandler接口。
InvocationHandler 类是JDK反射包中的一个接口方法,它定义了一个invoke接口方法。通常就是通过反射来实现。
MapperProxy实现了InvocationHandler 接口,并重写了invoke方法,从它的代码实现逻辑中,我们可以看到,实际是调用了Method的invoke方法,也即通过传入的Class/Method参数,使用反射技术,实现方法调用。


再者,类似于Proxy.newProxyInstance 方法,MapperProxyFactory提供了创建代理实例的方法;

然后,在MapperRegistry类的getMapper方法中,我们发现;通过传入被代理对象的Class类,我们可以得到上述的MapperProxyFactory,进而可以得到代理对象MapperProxy。
最后,根据上述流程,当我们调用代理方法时,就会根据Class对象、Method方法,最总通过上述的一系列调用传递,最终通过反射来实现动态代理调用。


![[BUUCTF从零单排] Web方向 03.Web入门篇之sql注入-1(手工注入详解)](https://i-blog.csdnimg.cn/direct/9645f6e7b5a945c9b15df3265272820d.png#pic_center)

















