代理模式,就是为其他对象(接口)提供一个代理对象,用来控制对这个对象(接口)的访问或
增强其某个方法的功能,比如对传递的消息进行预处理、过滤,打印日志等等。实现这个需
求的最直接的方式是静态代理,但由于需要为每个被代理的目标类都编写一个代理类,增加
了编码的工作量,而动态代理则改善了这一点不足
静态代理
通过给某个目标类实现一个代理类,在不修改目标类代码的前提下增强其功能
假如现在有一个需求,要在现有类的所有方法前后打印日志,具体做法:
为现有的每一个类都编写一个对应的代理类,并且让它实现和目标类相同的接口
在创建代理对象时,通过构造器塞入一个目标对象,然后在代理对象的方法内部调用目
标对象同名方法,并在调用前后打印日志。即 代理对象=增强代码+原对象
,有了代理
对象后,就不用原对象了
动态代理
JDK 提供了 java.lang.reflect.InvocationHandler 接口和 java.lang.reflect.Proxy 类,
这两个类相互配合
Proxy 类
Proxy 有个静态方法: getProxyClass(ClassLoader, interfaces)
,只要你给它传入类加
载器和一组接口,它就给你返回代理 Class 对象
用通俗的话说,getProxyClass 这个方法,会从你传入的接口 Class 中,“拷贝”类结构信息到
一个新的 Class 对象中,但新的 Class 对象带有构造器,是可以创建对象的。所以,一旦我们
明确接口,完全可以通过接口的 Class 对象,创建一个代理 Class,通过代理 Class 即可创建
代理对象(反射机制 )
![](/ox-hugo/2021-10-23_11-05-47_screenshot.png” caption=“<span class=“figure-number”>Figure 1: 静态代理)
![](/ox-hugo/2021-10-23_11-06-52_screenshot.png” caption=“<span class=“figure-number”>Figure 2: 动态代理)
从上图可以看出,相比于静态代理,动态代理不需要编写代理类就可以拿到代理对象,那么
剩下的工作就是给代理对象增加额外的代码来增强原对象的功能了
InvocationHandler
根据代理 Class 的构造器创建对象时,需要传入 InvocationHandler,并将目标对象传入
InvocationHandler。每次调用代理对象的方法,最终都会调用 InvocationHandler 的 invoke
方法:
因此在 invoke 方法中,可以对目标对象的方法进行额外增强
示例代码
Proxy . newProxyInstance ( ClassLoader loader , Class < ? > [] interfaces , InvocationHandler h )
CLassLoader loader:指定动态代理类的类加载器
Class<?> interfaces:指定动态代理类需要实现的所有接口,需要被增强的接口列表
InvocationHandler h:指定与动态代理类关联的 InvocationHandler 对象
import java . lang . reflect . InvocationHandler ;
import java . lang . reflect . Method ;
import java . lang . reflect . Proxy ;
public class proxyTest {
public static void main ( String [] args ) {
DynamicSubject sub = new RealDynamicSubject ();
Handler handler = new Handler ( sub ); // 处理器类
DynamicSubject sub2 = ( DynamicSubject ) Proxy . newProxyInstance ( DynamicSubject . class . getClassLoader (), new Class []{ DynamicSubject . class }, handler );
DynamicSubject sub3 = ( DynamicSubject ) Proxy . newProxyInstance ( DynamicSubject . class . getClassLoader (), sub . getClass (). getInterfaces (), handler );
DynamicSubject sub4 = ( DynamicSubject ) Proxy . newProxyInstance ( DynamicSubject . class . getClassLoader (), RealDynamicSubject . class . getInterfaces (), handler );
System . out . println ( "sub.getClass() = " + sub . getClass ());
System . out . println ( "DynamicSubject.class = " + DynamicSubject . class );
System . out . println ( new Class []{ DynamicSubject . class });
System . out . println ( RealDynamicSubject . class . getInterfaces ());
sub2 . request ();
sub3 . request ();
sub4 . request ();
}
}
interface DynamicSubject { abstract void request (); }
class RealDynamicSubject implements DynamicSubject {
public void request () { System . out . println ( "From real subject." ); }
}
class Handler implements InvocationHandler {
private Object obj ; // 被代理的对象
@Override
public Object invoke ( Object proxy , Method method , Object [] args ) throws Throwable {
System . out . println ( "Do something before requesting: print log" );
Object xxx = method . invoke ( this . obj , args ); // 调用原对象的方法
System . out . println ( "Do something after requesting: print log" );
return xxx ;
}
public Handler ( Object obj ) {
this . obj = obj ;
}
}
Code Snippet 1:
demo