写在前面
关于JDK动态代理的源码中一些意图没有完全明白,待以后慢慢补充
关于代理的理解
代理的本质就是类功能的加强。
比如类A实现的功能是a,通过代理类ProxyA可以实现功能a+b。
代理分为静态代理、动态代理
静态代理又分两种实现:继承和聚合,聚合跟装饰器很像,就是把需要代理的实例传入进来
其实都是想办法如何重写父类的方法,进行功能加强
JDK动态代理就是提供需要代理的接口、方法功能加强的逻辑实现,JDK会自动帮我们生成一个代理类,并加载到JVM中。
使用
接口
public interface ITestService {
void saySomething(String str);
}
复制代码
实现
public class TestServiceImpl implements ITestService {
@Override
public void saySomething(String str) {
System.out.println(str);
}
}
复制代码
InvocationHandler实现
public class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(Object object) {
this.target = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("写在sayHello之前");
method.invoke(target, args);
System.out.println("写在sayHello之后");
return null;
}
}
复制代码
功能验证
public class ProxyTest {
public static void main(String[] args) {
ITestService target = new TestServiceImpl();
InvocationHandler handler = new MyInvocationHandler(target);
ITestService proxy = (ITestService) Proxy.newProxyInstance(ProxyTest.class.getClassLoader(),
target.getClass().getInterfaces(), handler);
proxy.saySomething("hello");
}
}
复制代码
结果输出
一些疑问
- JDK生成的代理类为什么要继承Proxy类?
如果输出JDK生成的动态代理类字节码,将其反编译,会发现它会继承Proxy。
JDK这么做应该是有设计上的考量。继承Proxy这个类是否有其必要性?
从结果上看,一个类如果做了继承那么这个类就不能以继承的方式实现代理,也就是不能代理类。
而动态代理以继承的方式代理类是非常困难的,比如一个类的final方法是不可重写的;一个类可以非常庞大,可以有很多属性,以继承的方式代理也会有不必要的资源浪费。
而Java动态生成的代理类继承Proxy,是不是想表达“Java的动态代理的实现是不支持代理类”这个意思呢?
- 源码疑问
ProxyGenerator.generateProxyClass生成代理类的字节码,是怎么做的?
Proxy.defineClass0是个本地方法,将代理类的字节码加载到JVM中,这又是怎么做的?
源码中有很多权限验证和包路径验证,对其意图不是很明确。
转载于:https://juejin.im/post/5d09e1a3f265da1bc07e3d8a