原创声明:本博客来源与本人另一博客【http://blog.csdn.net/liaohaojian/article/details/63683317】原创作品,绝非他处摘取

代理(proxy)的定义:为某对象提供代理服务,拥有操作代理对象的功能,在某些情况下,当客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

动态代理实现主要有2种形式,主要分为: 
1.jdk动态代理: 
1)原理:是根据类加载器和接口创建代理类(此代理类是接口的实现类,所以必须使用接口 面向接口生成代理,位于java.lang.reflect包下) 
2)实现方式: 
1. 通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(…); 
2. 通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…}); 
3. 通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class}); 
4. 通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler)); 
2~4步骤可合并

Java代码  

  1. package proxy.jdkproxy;  

  2.   

  3. import java.lang.reflect.InvocationHandler;  

  4. import java.lang.reflect.Method;  

  5. import java.lang.reflect.Proxy;  

  6.   

  7. import org.junit.Test;  

  8.   

  9. public class JDKProxy{  

  10.     //写法1  

  11.     private Object targetObject;//代理目标  

  12.     public Object CustomerProxy(Object obj) {  

  13.         targetObject = obj;  

  14.         return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(),new targetHandler());  

  15.     }  

  16.     class targetHandler  implements InvocationHandler{  

  17.         @Override  

  18.         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  

  19.              System.out.println("开启事务...");    

  20.              Object returnValue = method.invoke(targetObject, args);//回调被代理目标的方法userDaoImpl.add();    

  21.              System.out.println("提交事务");    

  22.              return returnValue;    

  23.         }  

  24.     }  

  25.     public static void main(String[] args) {    

  26.         JDKProxy jdkProxy = new JDKProxy();    

  27.         Customer userDao = (Customer)jdkProxy.CustomerProxy(new CustomerImpl());    

  28.         userDao.shopping();    

  29.     }    

  30.     //写法2  

  31.     @Test  

  32.     public void test1(){  

  33.         Customer customer = new CustomerImpl();  

  34.         Customer cus = (Customer) Proxy.newProxyInstance(customer.getClass().getClassLoader(), customer.getClass().getInterfaces(),new InvocationHandler(){  

  35.             @Override  

  36.             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  

  37.                 // TODO Auto-generated method stub  

  38.                 return method.invoke(proxy, args);  

  39.             }  

  40.   

  41.         });  

  42.         cus.shopping();  

  43.     }  

  44. }  

 

3)不足点:jdk动态代理,必须是面向接口,目标业务类必须实现接口 
2.CGLIB代理 
1.原理:利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。 
2.实现方法:

Java代码  

  1. package proxy.cglib;  

  2. import java.lang.reflect.Method;  

  3. import org.junit.Test;  

  4. import net.sf.cglib.proxy.Enhancer;  

  5. import net.sf.cglib.proxy.MethodInterceptor;  

  6. import net.sf.cglib.proxy.MethodProxy;  

  7. import proxy.model.Customer;  

  8.   

  9. public class CGLIBProxy {  

  10.     //写法1  

  11.     private Object targetObject;  

  12.     private Object createProxy(Object obj){  

  13.         targetObject = obj;  

  14.         Enhancer enhancer = new Enhancer();  

  15.         enhancer.setSuperclass(targetObject.getClass());//设置代理对象,父类,说明是继承,所有代理对象不能为final  

  16.         enhancer.setCallback(new MyHandler());  

  17.         return enhancer.create();//创建代理  

  18.     }  

  19.     class MyHandler implements MethodInterceptor{  

  20.         @Override  

  21.         public Object intercept(Object arg0, Method method, Object[] args,  

  22.                 MethodProxy arg3) throws Throwable {  

  23.             System.out.println("开启事务..");    

  24.             Object returnValue = method.invoke(targetObject, args);    

  25.             System.out.println("提交事务....");    

  26.             return returnValue;    

  27.         }  

  28.     }  

  29.     @Test  

  30.     public  void test1() {    

  31.         CGLIBProxy cglibProxy = new CGLIBProxy();    

  32.         Customer customer = (Customer)cglibProxy.createProxy(new Customer());    

  33.         customer.eat();    

  34.     }    

  35.     //写法2  

  36.     @Test  

  37.     public void test2(){  

  38.         Customer customer = new Customer();  

  39.         Enhancer enhancer = new Enhancer();  

  40.         enhancer.setSuperclass(customer.getClass());  

  41.         enhancer.setCallback(new MethodInterceptor() {  

  42.             @Override  

  43.             public Object intercept(Object proxy, Method method, Object[] args,  

  44.                     MethodProxy arg3) throws Throwable {  

  45.                 if(method.getName().equals("eat")){    

  46.                     System.out.println("customer的eat方法被拦截了。。。。");    

  47.                     Object invoke = method.invoke(proxy, args);    

  48.                     System.out.println("真实方法拦截之后。。。。");    

  49.                     return invoke;    

  50.                 }    

  51.                 // 不拦截    

  52.                 return method.invoke(proxy, args);    

  53.             }  

  54.         });  

  55.         Customer cus = (Customer) enhancer.create();  

  56.         cus.eat();  

  57.     }  

  58. }  

3.注意点:被代理目标不是是final修饰的类(final修饰类不能被继承) 
spring aop代理原理 
1.注意点:

  • 如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP

  • 如果目标对象实现了接口,可以强制使用CGLIB实现AOP

  • 如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

2.强制把jdk代理转换成cglib代理

  • 添加CGLIB库,SPRING_HOME/cglib/*.jar

  • 在spring配置文件中加入这里写图片描述
    传统AOP可以实现自动代理,不需要专门指定代理,可以在类生成的时候自动代理,有两种方式实现自动代理,基于Bean名称的自动代理BeanNameAutoProxyCreator和基于切面信息的自动代理DefaultAdvisorAutoProxyCreator

spring mvc 使用DefaultAdvisorAutoProxyCreator实现自动代理 配置

Java代码  

  1.   

  2.     "autoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>  

  3.       

  4.     "exceptionHandler" class="com.kaizhi.platform.util.ExceptionHandler"/>  

  5.       

  6.     "exceptionHandlerAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">               

  7.         "advice">  

  8.             "exceptionHandler"/>  

  9.           

  10.         "patterns">  

  11.             .save*.*//正则匹配需要拦截的方法  

  12.           

  13.        

spring mvc 使用BeanNameAutoProxyCreator自动代理配

Java代码  

  1.     

  2.       

  3.     "exceptionHandler" class="com.kaizhi.platform.util.ExceptionHandler"/>  

  4.     class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">    

  5.             

  6.         "beanNames" value="*adminFinanceService"/>    

  7.             

  8.         "interceptorNames" value="exceptionHandler"/>    

  9.       

参考:http://blog.csdn.net/zx13525079024/article/details/51913141