java动态代理(JDK和cglib)

java动态代理(JDK和cglib)

细说JDK动态代理的实现原理

两者都是通过创建字节码的技术来创建代理类

JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能使用JDK的动态代理。因为通过动态代理生成的类已经继承了Proxy类了并实现要代理的接口,不能再继承其他的类了。

CGLIB是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。



如果想要保存动态代理生成的.class文件,两种动态代理方式可以使用如下两种方式配置系统属性进行保存。

//保存JDK动态代理生成的class文件System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");

//保存CGLIB动态代理生成的class文件System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"C:\\Users\\wange\\Desktop\\study\\com\\sun\\cglib");

另外发现JDK动态代理的代理类是在初始化SPRING容器的时候一次性生成所有的代理类,然后进行依赖注入的时候直接注入代理类。

还发现不管切面有多少个,生成的代理类始终是下面这一些,应该是对InvocationHandler按照顺序进行了多级代理处理。比如真实对象是useService,$Proxy0先代理了useService,然后$Proxy1又代理了$Proxy0,但是最终只生成和保留$Proxy1这个类。有点乱,按结果来看是这样,不知道具体是怎么操作的。这点和SPRING MVC里面的拦截器貌似有点不同,拦截器是基于责任链的方式来调用的,因此代理类必须每个都存在。

java动态代理(JDK和cglib)_第1张图片

而CGLIB则是在初始化SPRING容器会生成一个主要的类,然后在创建对象和调用方法的时候又创建了两个继承了FastClass代理类,我也不知道是什么东西。

比如下面的三条语句,每运行一条分别生成如下的每一个文件(还有另外生成的spring框架代理类就不看了)。这三个类的class文件进行JAD反编译后的结果如下。


java动态代理(JDK和cglib)_第2张图片

你可能感兴趣的:(java动态代理(JDK和cglib))