Spring的两种代理JDK和CGLIB的区别
(原文地址:http://blog.csdn.net/u013126379/article/details/52121096)
一、原理区别:
jdk动态代理:构造方法动态传入实例对象,使用Proxy根据目标类的类加载器、接口数组和调用处理者InvocationHandler作为参数来newProxyInstance。
cglib动态代理:使用Enhance设置实现MethodInterceptor接口的代理类属性与父类的Class属性,便可使用enhance的create创建代理子类对象。
java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
如何强制使用CGLIB实现AOP?
(1)添加CGLIB库,SPRING_HOME/cglib public class JDKProxy implements InvocationHandler { private Object targetObject;//需要代理的目标对象 public Object newProxy(Object targetObject) {//将目标对象传入进行代理 this.targetObject = targetObject; return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);//返回代理对象 } public Object invoke(Object proxy, Method method, Object[] args)//invoke方法 throws Throwable { checkPopedom();//一般我们进行逻辑处理的函数比如这个地方是模拟检查权限 Object ret = null; // 设置方法的返回值 ret = method.invoke(targetObject, args); //调用invoke方法,ret存储该方法的返回值 return ret; } private void checkPopedom() {//模拟检查权限的例子 System.out.println(".:检查权限 checkPopedom()!"); } }