动态代理
动态代理
动态代理是指,程序在整个运行的过程中根本不存在目标的代理类,目标对象的代理对象只是由代理生成工具(不是真是定义的类)在程序运行时由JVM 根据反射等机制动态生成的。代理对象与目标对象的代理关系在程序运行时才确定。
1. JDK动态代理
动态代理的实现方式常用的有两种:使用JDK 的Proxy,与通过CGLIB生成代理。JDK的动态要求目标对象必须实现接口,这是java设计上的要求。从jdk1.3以来,java语言通过java.lang.reflect包提供的三个类支持代理模式Proxy,Method和InvocationHandler.
2. CGLIB动态代理
CGLIB(Code Generation Library)是一个开源项目。是一个强大的,高性能,高质量的Code生成的类库,它可以在运行期扩展java类与实现java接口。它广泛的被许多AOP 的框架使用。如:Spring AOP.
使用 JDK 的 Proxy 实现代理,要求目标类与代理实现相同的接口。若目标类不存在接口,则无法实现该方式。但对于无接口的类,要为其创建动态代理,就要使用CGLIB来实现。
3. 动态代理的作用
1)在目标类源代码不改变的情况下,增强功能。
2)减少代码的重复。
3)专注业务逻辑代码。
4)解耦合,让你的业务功能和日志,事务和非业务功能分离。
应用代码
-
创建目标类
-
创建InvocationHanler接口的实现类,在这个类实现给目标方法增强功能。
package org.example.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class UserDaoEnhance implements InvocationHandler {
//目标对象
Object target = null;
public UserDaoEnhance(Object target) {
this.target = target;
}
//通过代理对象执行方法时,会调用这个invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("执行前增强.....");
//执行目标类方法,通过Method类实现
Object result = method.invoke(target, args);
System.out.println("执行后增强.....");
//目标方法的执行结果
return result;
}
}
- 使用JDK中类Proxy,创建代理对象,实现创建对象的能力。
@Test
public void test4(){
//创建目标对象
UserDao target = new UserDaoImpl();
//创建InvocationHandler对象
InvocationHandler handler = new UserDaoEnhance(target);
//使用Proxy创建代理
UserDao userDao = (UserDao) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);
//通过代理执行方法,调用handler中的invoke方法
userDao.run();
}