淘先锋技术网

首页 1 2 3 4 5 6 7

Spring的两种代理JDK和CGLIB的区别


(原文地址:http://blog.csdn.net/u013126379/article/details/52121096


一、原理区别:

jdk动态代理:构造方法动态传入实例对象,使用Proxy根据目标类的类加载器、接口数组和调用处理者InvocationHandler作为参数来newProxyInstance

cglib动态代理:使用Enhance设置实现MethodInterceptor接口的代理类属性与父类的Class属性,便可使用enhancecreate创建代理子类对象。


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()!");    
  •     }    
  • }