环境
运行:
源码解读
我们发现通过Proxy类的方法返回了一个代理类对象,传入了三个参数,分别时类加载器、被代理类、自定义类实现InvocationHandler接口并重写invoke方法实现增强。
进入该方法查看:
这个方法包括三个重要步骤:
步骤1:根据接口和类加载器通过反射构造代理类
步骤2:根据参数获取构造器,这个参数是InvocationHandler类
步骤3:通过构造器和传入的InvocationHandler创建代理对象
我们先查看代理类:
可以看到代理类继承了Proxy类并且实现了代理类的接口,其包含了五个方法名,这些方法名在类加载时就被初始化:
这个构造方法调用了父类的构造方法,查看:
其继承了父类的InvocationHandler属性,并调用了父类的构造方法对InvocationHandler进行了赋值。
我们查看代理类的方法:
当调用代理对象的方法时,会被中转到InvocationHandler对象中的invoke方法中,如下图:
增强逻辑
自定义一个类实现InvocationHandler接口,调用Proxy的newProxyInstance在运行时会创建一个代理类,这个代理类继承了Proxy并且实现了被代理类接口,创建代理对象时传递了传入的InvocationHandler实现类,通过父类完成初始化和InvocationHandler的赋值,当调用代理对象的方法时都会中转到InvocationHandler实现类的invoke方法中,通过增强逻辑后,通过反射调用原方法。
JDK动态代理的区别
生成代理类的方式:JDK基于反射生成代理类(继承Proxy实现被代理接口),CGLIB通过ASM字节码库生成代理类(继承被代理类)
对被代理类要求:JDK要求被代理类是个接口,CGLIB要求被代理类可以被继承,不能被final修饰
代理增强后如何调用原方法:JDK通过反射调用原方法,CGLIB通过FastClass的索引调用