定义
动态代理是指在代码运行过程中,使用反射机制创建代理对象,并动态指定代理对象的目标类。动态代理分为jdk和cglib动态代理两种,在不改变原来目标方法功能的前提下,可以在代理中增强自己功能代码。
JDK动态代理
JDK动态代理基于反射机制实现的,使用jdk反射包下的Proxy和InvovationHandler实现代理对象的动态创建,其中方法拦截器调用了InvovationHandler接口,并重写了invoke方法。在创建代理对象时,使用Proxy.newProxyInstance传入类加载器、目标对象实现的接口、方法拦截器创建代理对象,强制转化后即可得到实际需要的代理对象。
JDK代理对象是委托机制,只能对实现接口的类生成代理,并通过反射动态实现接口类。同时JDK创建代理对象效率高,但执行效率低。以下为一个代码示例:
//接口
public interface Test {
public int add(int x, int y);
}
//接口实现类
public class Test1 implements Test{
public int add(int x, int y) {
System.out.println("加法运算执行中");
return x + y;
}
}
//方法拦截器
public class Handler implements InvocationHandler {
//指定传入的类
private Object target;
//构造函数
public Handler(Object target) {
this.target = target;
}
//调用生成代理对象方法时会执行
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object res = method.invoke(target, args);
System.out.println("代理对象正在加强中");
return res;
}
}
import java.lang.reflect.Proxy;
//测试类
public class DynamicTest {
public static void main(String[] args) {
//创建目标代理对象
Test1 test1 = new Test1();
//创建方法拦截器
Handler handler = new Handler(test1);
//生成动态代理对象
Test test = (Test)Proxy.newProxyInstance(test1.getClass().getClassLoader(), test1.getClass().getInterfaces(), handler);
int sum = test.add(1,2);
System.out.println("求和值:"+sum);
}
}
CGLIB动态代理
CGLIB动态代理与JDK动态代理不同,可代理具体的类,针对类的实现代理,被代理类和代理类是继承关系,被代理类不能使用final修饰。其底层使用字节码处理框架asm,将代理对象的class加载进来,通过修改字节码生成子类,其创建代理对象效率低,执行效率高。
CGLIB动态代理需实现MethodInterceptor,并重写intercept(),使用Enhancer对象.create()生成代理对象。