JDK动态代理要点:
- 类:java.lang.reflect.Proxy(动态生成代理类)
- 接口:java.lang.reflect.InvocationHandler (代理类需要实现的逻辑)
- 只能基于接口进行动态代理
1.1 如何使用JDK动态代理:调用invoke接口
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
Subject、RealSubject和静态代理一样,只有代理类修改如下:
// 和静态代理的区别:代理类实现了InvocationHandler接口,和实际对象实现的不是同一接口
public class JdkProxySubject implements InvocationHandler{
private RealSubject realSubject;
// 动态代理也需要引用实际对象
public void JdkProxySubject (RealSubject realSubject) {
this.realSubject = realSubject;
}
// 关键在于实现了接口的invoke方法
@Override
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
// 这样就实现了在实际request之前和之后的操作
before();
// 利用反射,来动态调用目标对象的方法,这样就不用在代理类中显式调用request方法
// 所以就不需要每个方法都写一套代理了
Object result = method.invoke(realSubject, args);
after();
return result;
}
}
以上基于方法的反射,就是动态代理和静态代理的区别。
如果使用静态代理,那新增一个方法,需要在代理类里面也新增方法并且增加对应的委托代码;但是JDK动态代理类任何都不变,就可以实现。
public class Client{
public static void main(String[] args) {
// Client首先要把真实类构造出来:通过Proxy来构造
// 通过Proxy构造出来,传入JdkProxySubject动态代理对象,那在调用request方法的时候会执行代理类的inovke
Subject subject = (Subject)Proxy.newProxyInstance(Client.class.getClassLoader(), new Class[]{Subject.class}, new JdkProxySubject(new RealSubject()));
subject.request();
}
}
网友评论