动态代理作用:功能增强和控制访问
动态代理(理解)
动态代理是指,程序在整个运行过程中根本就不存在目标类的代理类,目标对象的代理对象只是由代理生成工具(不是真实定义的类)在程序运行时由 JVM 根据反射等机制动态生成的。代理对象与目标对象的代理关系在程序运行时才确立。
对比静态代理,静态代理是指在程序运行前就已经定义好了目标类的代理类。代理类与目标类的代理关系在程序运行之前就确立了。
动态代理的实现方式常用的有两种:使用 JDK 的 Proxy,与通过 CGLIB 生成代理。
Jdk 的动态要求目标对象必须实现接口,这是 java 设计上的要求。
从 jdk1.3 以来,java 语言通过 java.lang.reflect 包提供三个类支持代理模式 Proxy, Method和 InovcationHandler。
A、通过 JDK 的 java.lang.reflect.Proxy 类实现动态代理,会使用其静态方法
newProxyInstance(),依据目标对象、业务接口及调用处理器三者,自动生成一个动态代理对象。
public static newProxyInstance ( ClassLoaderloader, Class []interfaces, InvocationHandlerhandler)
loader:目标类的类加载器,通过目标对象的反射可获取
interfaces:目标类实现的接口数组,通过目标对象的反射可获取
handler:调用处理器。
B、 InvocationHandler 是个接口,其具体介绍如下:
实现了 InvocationHandler 接口的类用于加强目标类的主业务逻辑。这个接口中有一个方法 invoke(),具体加强的代码逻辑就是定义在该方法中的。程序调用主业务逻辑时,会自动调用 invoke()方法。
//Object proxy:代理对象
//Method m :调用的方法
//Object [] args: 调用方法的参数
public Object invoke(Object proxy, Method m, Object[] args)
C、 Method 类对象,该类有一个方法也叫 invoke(),可以调用目标类的目标方法。
这两个 invoke()方法,虽然同名,但无关。
public Object invoke ( Object obj, Object... args)
obj:表示目标对象args:表示目标方法参数,就是其上一层 invoke 方法的第三个参数
CGLIB 动态代理(理解)
CGLIB(Code Generation Library)是一个开源项目。是一个强大的,高性能,高质量的 Code生成类库,它可以在运行期扩展 Java 类与实现 Java 接口。它广泛的被许多 AOP 的框架使用,例如 Spring AOP。
使用 JDK 的 Proxy 实现代理,要求目标类与代理类实现相同的接口。若目标类不存在接口,则无法使用该方式实现。但对于无接口的类,要为其创建动态代理,就要使用 CGLIB来实现。
CGLIB 代理的生成原理是生成目标类的子类,而子类是增强过的,这个子类对象就是代理对象。所以,使用 CGLIB 生成动态代理,要求目标类必须能够被继承,即不能是 final 的类。
CGLIB 经常被应用在框架中,例如 Spring ,Hibernate 等。cglib 的代理效率高于 Jdk。
项目中直接使用动态代理的地方不多。一般都使用框架提供的功能。
(1) 导入 jar
(2) 定义目标类
SomeSerivce.java ,有 String doSome()方法
(3) 定义调用处理器,实现 MethodInterceptor 接口
(4) 定义代理工厂类,创建代理对象
(5) 定义客户端类