Spring AOP的两种代理方式

转载:https://blog.csdn.net/l1028386804/article/details/80295523

Spring AOP主要有两种代理方式:

1.JDK动态代理  2.cglib代理
1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
注:JDK动态代理要比cglib代理执行速度快,但性能不如cglib好。所以在选择用哪种代理还是要看具体情况,一般单例模式用cglib比较好,具体原因请自行百度。

一、JDK动态代理实现(原理是使用反射机制)

1、定义TestService接口

[java]  view plain  copy
  1. package io.mykit.proxy.jdk.service;  
  2.   
  3. /** 
  4.  * JDK动态代理Service 
  5.  * @author liuyazhuang 
  6.  * 
  7.  */  
  8. public interface TestService {  
  9.       
  10.     int add();  
  11. }  

2、定义TestServiceImpl实现类

[java]  view plain  copy
  1. package io.mykit.proxy.jdk.service.impl;  
  2.   
  3. import io.mykit.proxy.jdk.service.TestService;  
  4.   
  5. public class TestServiceImpl implements TestService {  
  6.   
  7.     @Override  
  8.     public int add() {  
  9.         System.out.println("开始执行add...");  
  10.         return 0;  
  11.     }  
  12.   
  13. }  

3、定义动态代理类JDKDynamicProxy

[java]  view plain  copy
  1. package io.mykit.proxy.jdk.handler;  
  2.   
  3. import java.lang.reflect.InvocationHandler;  
  4. import java.lang.reflect.Method;  
  5. import java.lang.reflect.Proxy;  
  6.   
  7. /** 
  8.  * JDK的动态代理实现 
  9.  * @author liuyazhuang 
  10.  * 
  11.  */  
  12. public class JDKDynamicProxy implements InvocationHandler {  
  13.   
  14.      //被代理的目标对象  
  15.     private Object proxyObj;    
  16.      
  17.     /** 
  18.      * Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 
  19.      * loader    :类加载器 一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载 
  20.      * interfaces:一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了 
  21.      * h         :一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上 
  22.      */  
  23.       public Object newProxy(Object proxyObj){    
  24.           this.proxyObj = proxyObj;  
  25.           //返回一个代理对象    
  26.           return Proxy.newProxyInstance(proxyObj.getClass().getClassLoader(), proxyObj.getClass().getInterfaces(), this);    
  27.       }    
  28.   
  29.      /** 
  30.       * 执行目标对象 
  31.       * Object  proxy:被代理的对象 
  32.       * Method  method:要调用的方法 
  33.       * Object  args[]:方法调用时所需要的参数 
  34.       */  
  35.        @Override  
  36.        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        
  37.             before();  
  38.             Object object = method.invoke(this.proxyObj, args);  // 通过反射机制调用目标对象的方法  
  39.             after();        
  40.             return object;    
  41.         }  
  42.         public void before(){  
  43.              System.out.println("开始执行目标对象之前...");  
  44.         }  
  45.         public void after(){  
  46.             System.out.println("开始执行目标对象之后...");  
  47.     }  
  48. }  

4、实现测试类ProxyTest

[java]  view plain  copy
  1. package io.mykit.proxy.jdk;  
  2.   
  3. import io.mykit.proxy.jdk.handler.JDKDynamicProxy;  
  4. import io.mykit.proxy.jdk.service.TestService;  
  5. import io.mykit.proxy.jdk.service.impl.TestServiceImpl;  
  6.   
  7. /** 
  8.  * 动态代理测试 
  9.  *  
  10.  * @author liuyazhuang 
  11.  * 
  12.  */  
  13. public class ProxyTest {  
  14.       
  15.     public static void main(String[] args) {  
  16.         // 我们要代理的真实对象  
  17.         TestService testService = new TestServiceImpl();  
  18.         testService.add();// 不是用代理  
  19.         System.out.println("===================================");  
  20.         JDKDynamicProxy JDKDynamicProxyTarget = new JDKDynamicProxy();  
  21.         TestService testServiceProxy = (TestService) JDKDynamicProxyTarget.newProxy(testService);  
  22.         // 执行代理类的方法  
  23.         testServiceProxy.add();  
  24.     }  
  25. }  

5、测试结果如下

[plain]  view plain  copy
  1. 开始执行add...  
  2. ===================================  
  3. 开始执行目标对象之前...  
  4. 开始执行add...  
  5. 开始执行目标对象之后...  

二、CGLIB代理

1、创建TestCGLIBServiceImpl类

[java]  view plain  copy
  1. package io.mykit.proxy.cglib.service.impl;  
  2. /** 
  3.  * 未实现接口的类 
  4.  * @author liuyazhuang 
  5.  * 
  6.  */  
  7. public class TestCGLIBServiceImpl {  
  8.     public int add() {  
  9.         System.out.println("开始执行add...");  
  10.         return 0;  
  11.     }  
  12.  }  

2、创建代理类CGLIBProxy

[java]  view plain  copy
  1. package io.mykit.proxy.cglib.handler;  
  2.   
  3. import java.lang.reflect.Method;  
  4. import net.sf.cglib.proxy.Enhancer;  
  5. import net.sf.cglib.proxy.MethodInterceptor;  
  6. import net.sf.cglib.proxy.MethodProxy;  
  7.   
  8. /** 
  9.  * 基于CGLIB实现 
  10.  * @author liuyazhuang 
  11.  * 
  12.  */  
  13. public class CGLIBProxy implements MethodInterceptor {  
  14.   
  15.     private Object targetObject;// 被代理的目标对象  
  16.   
  17.     /** 
  18.      * 构造代理对象 
  19.      * @param targetObject 传递的真实对象 
  20.      * @return 代理对象 
  21.      */  
  22.     public Object createProxyInstance(Object targetObject) {  
  23.         this.targetObject = targetObject;  
  24.         Enhancer enhancer = new Enhancer();  
  25.         enhancer.setSuperclass(targetObject.getClass());// 设置代理目标  
  26.         enhancer.setCallback(this);// 设置回调  
  27.         return enhancer.create();  
  28.     }  
  29.   
  30.     /** 
  31.      * 在代理实例上处理方法调用并返回结果 
  32.      * @param object : 代理类 
  33.      * @param method  :被代理的方法 
  34.      * @param args :该方法的参数数组 
  35.      * @param methodProxy : 方法代理 
  36.      */  
  37.     @Override  
  38.     public Object intercept(Object object, Method method, Object[] args, MethodProxy methodproxy) throws Throwable {  
  39.         Object result = null;  
  40.         try {  
  41.             System.out.println("前置处理开始 ...");  
  42.             result = methodproxy.invoke(targetObject, args);// 执行目标对象的方法  
  43.             System.out.println("后置处理开始  ...");  
  44.         } catch (Exception e) {  
  45.             System.out.println(" 异常处理 ...");  
  46.         } finally {  
  47.             System.out.println(" 调用结束 ...");  
  48.         }  
  49.         return result;  
  50.     }  
  51. }  

3、创建测试类ProxyTest

[java]  view plain  copy
  1. package io.mykit.proxy.cglib;  
  2.   
  3. import io.mykit.proxy.cglib.handler.CGLIBProxy;  
  4. import io.mykit.proxy.cglib.service.impl.TestCGLIBServiceImpl;  
  5.   
  6. /** 
  7.  * 测试CGLIB代理 
  8.  * @author liuyazhuang 
  9.  * 
  10.  */  
  11. public class ProxyTest {  
  12.       
  13.      public static void main(String[] args) {  
  14.          //我们要代理的真实对象  
  15.          TestCGLIBServiceImpl testCGLIB = new TestCGLIBServiceImpl();  
  16.          testCGLIB.add();  
  17.          System.out.println("======================================");  
  18.          CGLIBProxy CGLIBproxy = new CGLIBProxy();  
  19.          TestCGLIBServiceImpl testCGLIBProxy = (TestCGLIBServiceImpl) CGLIBproxy.createProxyInstance(testCGLIB);  
  20.          testCGLIBProxy.add();  
  21.       }  
  22. }  

4、测试结果

[plain]  view plain  copy
  1. 开始执行add...  
  2. ======================================  
  3. 前置处理开始 ...  
  4. 开始执行add...  
  5. 后置处理开始  ...  
  6.  调用结束 ...  

5、pom.xml中添加的Jar包

[html]  view plain  copy
  1. <properties>  
  2.     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
  3.     <skip_maven_deploy>false</skip_maven_deploy>  
  4.     <jdk.version>1.8</jdk.version>  
  5.     <spring.version>4.1.0.RELEASE</spring.version>  
  6. </properties>  
  7.   
  8. <dependencies>  
  9.      
  10.   <dependency>  
  11.         <groupId>org.springframework</groupId>  
  12.         <artifactId>spring-expression</artifactId>  
  13.         <version>${spring.version}</version>  
  14.     </dependency>   
  15.       
  16.         <dependency>  
  17.         <groupId>org.springframework</groupId>  
  18.         <artifactId>spring-messaging</artifactId>  
  19.         <version>${spring.version}</version>  
  20.     </dependency>  
  21.       
  22.     <dependency>  
  23.         <groupId>org.springframework</groupId>  
  24.         <artifactId>spring-jms</artifactId>  
  25.         <version>${spring.version}</version>  
  26.     </dependency>  
  27.       
  28.     <dependency>  
  29.         <groupId>org.springframework</groupId>  
  30.         <artifactId>spring-aop</artifactId>  
  31.         <version>${spring.version}</version>  
  32.     </dependency>  
  33.       
  34.     <dependency>  
  35.         <groupId>org.springframework</groupId>  
  36.         <artifactId>spring-jdbc</artifactId>  
  37.          <version>${spring.version}</version>  
  38.     </dependency>  
  39.       
  40.      <dependency>  
  41.         <groupId>org.springframework</groupId>  
  42.         <artifactId>spring-context</artifactId>  
  43.         <version>${spring.version}</version>  
  44.     </dependency>  
  45.   
  46.     <dependency>  
  47.         <groupId>org.springframework</groupId>  
  48.         <artifactId>spring-context-support</artifactId>  
  49.         <version>${spring.version}</version>  
  50.     </dependency>  
  51.       
  52.     <dependency>  
  53.         <groupId>org.springframework</groupId>  
  54.         <artifactId>spring-web</artifactId>  
  55.         <version>${spring.version}</version>  
  56.     </dependency>  
  57.       
  58.     <dependency>  
  59.         <groupId>org.springframework</groupId>  
  60.         <artifactId>spring-webmvc</artifactId>  
  61.         <version>${spring.version}</version>  
  62.     </dependency>  
  63.       
  64.     <dependency>  
  65.         <groupId>org.aspectj</groupId>  
  66.         <artifactId>aspectjtools</artifactId>  
  67.         <version>1.9.1</version>  
  68.     </dependency>  
  69.       
  70.     <dependency>  
  71.         <groupId>javax.servlet</groupId>  
  72.         <artifactId>javax.servlet-api</artifactId>  
  73.         <version>3.0.1</version>  
  74.     </dependency>  
  75.   
  76.     <dependency>    
  77.         <groupId>org.slf4j</groupId>    
  78.         <artifactId>slf4j-log4j12</artifactId>    
  79.         <version>1.7.2</version>    
  80.     </dependency>   
  81.       
  82.       <dependency>  
  83.         <groupId>commons-logging</groupId>  
  84.         <artifactId>commons-logging</artifactId>  
  85.         <version>1.1.1</version>  
  86.     </dependency>  
  87.      <dependency>  
  88.             <groupId>cglib</groupId>  
  89.             <artifactId>cglib-nodep</artifactId>  
  90.             <version>2.1_3</version>  
  91.         </dependency>  
  92.       
  93. </dependencies>  

猜你喜欢

转载自blog.csdn.net/u011109589/article/details/80305758