动态代理的意义在于生成一个占位(又称代理对象),来代理真实对象,从而控制真实对象的访问。
先来谈谈什么是代理模式。假设这样一个场景,你的公司是一家软件公司,你是一位软件工程师。客户带着需求去找公司显然不会和你直接去谈,而是去找商务,此时客户会认为商务就代表公司。
让我们用一张简图来表示一下代理模式的含义,如下图所示。
经过上面的论述,我们知道商务和软件工程师是代理和被代理的关系,客户是经过商务去访问软件工程师的。此时客户就是程序中的调用者,商务就是代理对象,软件工程师就是真实对象。我们需要在调用者调用对象之前产生一个代理对象,而这个代理对象需要和真实对象建立代理关系,所以代理必须分为两个步骤:
-
代理对象和真实对象建立代理关系。
-
实现代理对象中的代理逻辑方法。
在Java中有多种动态代理技术,比如JDK、CGLIB、Javassist、ASM,其中最常用的动态代理技术有两种:一种是JDK动态代理,另一种是第三方提供的CGLIB。目前,Spring常用JDK和CGLIB。无论哪种代理技术,它们的理念都是相似的。
下面通过代码看一下JDK动态代理和CGLIB动态代理。
JDK动态代理
- 先定义一个接口
CGLIB动态代理
JDK动态代理必须提供接口才能使用,在一些不能提供接口的环境中,只能采用其他第三方技术,比如CGLIB动态代理。它的优势在于不需要提供接口,只要一个非抽象类就能实现动态代理。
- 这里新建一个类作为测试。
这里用CGLIB的加强者Enhancer,通过设置超类的方法(setSuperclass),然后通过setCallback方法设置代理类。this意味着用当前对象实现接口MethodInterceptor的方法--intercept,然后返回代理对象。当前类的intercept方法就是其代理逻辑方法,参数内容见代码注解。
掌握了JDK动态代理就很容易掌握CGLIB动态代理,二者是相似的。它们都是用getProxy方法生成代理对象,制定代理的逻辑类。而代理逻辑类要实现一个接口的一个方法,那么这个接口定义的方法就是代理对象的逻辑方法,它可以控制真实对象的方法。
本文参考《Java EE 互联网轻量级框架整合开发》