深入了解动态代理及其实现方式

动态代理是指在Java进程运行时,通过字节码技术动态生成某个类的代理类。在代理类中,我们可以进行额外的操作,既保持原有方法的能力,又增强了这些能力。这种技术是AOP的基石。

在实现动态代理时,一般有两种方式:JDK动态代理和CGLIB动态代理。本文将重点介绍CGLIB动态代理的使用方法。

与JDK动态代理不同,CGLIB动态代理是将被代理类作为父类,派生出子类,代理类和被代理类均为继承关系,是“父子关系”,被代理的方法就是父类中公开的方法。

生成代理类的核心逻辑在com.example.demo.learncglib.ProxyFactory#create方法中。首先声明一个增强器:Enhancer enhancer。接着设置代理类父类:SuperStar.class。然后设置回调类(包含增强方法的类):? implements MethodInterceptor。最后调用增强类的创建方法就生成好了:enhancer.create()。

CGLIB动态代理的局限性主要与继承有关:无法动态代理final方法,因为子类无法复写;无法动态代理static,因为子类无法复写。相比之下,JDK动态代理和CGLIB各有优劣。虽然经过JDK动态代理的速度优化,Spring目前已经默认采用JDK动态代理,但这并不能说明CGLIB的设计方案更差。

设计和实现是两回事,未来CGLIB的实现思路经过优化,又胜出了,也并不能说明CGLIB的设计方案更好。目前的Spring Boot最新版本又采用了CGLIB作为默认的AOP实现方式,这也并不能说明CGLIB就比JDK动态代理方式要强了。

如果想要将运行时动态生成的class文件保存到磁盘中,可以在执行的代码处添加如下代码:System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "E:\\code\\common\\learn-design-pattern\\target\\cglib")。

标签:游戏攻略