Spring学习-- AOP入门动态代理

 AOP 的拦截功能是由 java 中的动态代理来实现的。说白了,就是在目标类的基础上增加切面逻辑,生成增强的目标类(该切面逻辑或者在目标类函数执行之前,或者目标类函数执行之后,或者在目标类函数抛出异常时候执行。不同的切入时机对应不同的Interceptor的种类,如BeforeAdviseInterceptor,AfterAdviseInterceptor以及ThrowsAdviseInterceptor等)。

 1 package com.itdoc.spring.aop.proxy;
 2 
 3 /**
 4  * http://www.cnblogs.com/goodcheap
 5  *
 6  * @author: Wáng Chéng Dá
 7  * @create: 2017-03-03 19:34
 8  */
 9 public interface Arithmetic {
10 
11     int add(int i, int j);
12 
13     int sub(int i, int j);
14 
15     int mul(int i, int j);
16 
17     int div(int i, int j);
18 
19 }
 1 package com.itdoc.spring.aop.proxy;
 2 
 3 /**
 4  * http://www.cnblogs.com/goodcheap
 5  *
 6  * @author: Wáng Chéng Dá
 7  * @create: 2017-03-03 19:35
 8  */
 9 public class ArithmeticProxyImpl implements Arithmetic {
10     @Override
11     public int add(int i, int j) {
12         int result = i + j;
13         return result;
14     }
15 
16     @Override
17     public int sub(int i, int j) {
18         int result = i - j;
19         return result;
20     }
21 
22     @Override
23     public int mul(int i, int j) {
24         int result = i * j;
25         return result;
26     }
27 
28     @Override
29     public int div(int i, int j) {
30         int result = i / j;
31         return result;
32     }
33 }
 1 package com.itdoc.spring.aop.proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 import java.lang.reflect.Proxy;
 6 import java.util.Arrays;
 7 
 8 /**
 9  * http://www.cnblogs.com/goodcheap
10  *
11  * @author: Wáng Chéng Dá
12  * @create: 2017-03-03 19:45
13  */
14 public class ArithmeticProxyHandle {
15 
16     //要代理的对象
17     private Arithmetic target;
18 
19     public ArithmeticProxyHandle(Arithmetic target) {
20         this.target = target;
21     }
22 
23     public ArithmeticProxyHandle() {
24     }
25 
26     public Arithmetic getLoggingProxy() {
27         Arithmetic proxy = null;
28         //代理对象由哪个类加载器负责加载
29         ClassLoader loader = target.getClass().getClassLoader();
30         //代理对象的类型, 即其中有哪些方法
31         Class [] interfaces = new Class[]{Arithmetic.class};
32         //当调用代理对象中的方法时, 执行该代码
33         InvocationHandler h = new InvocationHandler() {
34             /**
35              *
36              * @param proxy  正在返回的那个代理对象, 一般情况下, 在 invoke 方法中都不使用该对象。
37              * @param method 正在被调用的方法。
38              * @param args   调用方法时, 传入的参数。
39              * @return
40              * @throws Throwable
41              */
42             @Override
43             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
44                 String name = method.getName();
45                 System.out.println("The method " + name + " begins with" + Arrays.asList(args));
46                 Object result = method.invoke(target, args);
47                 System.out.println("The method " + name + "ends with " + result);
48                 return result;
49             }
50         };
51         proxy = (Arithmetic) Proxy.newProxyInstance(loader, interfaces, h);
52         return proxy;
53     }
54 }
 1 package com.itdoc.spring.aop.proxy;
 2 
 3 
 4 /**
 5  * http://www.cnblogs.com/goodcheap
 6  *
 7  * @author: Wáng Chéng Dá
 8  * @create: 2017-03-03 19:42
 9  */
10 public class Main {
11 
12     public static void main(String[] args) {
13         Arithmetic arithmetic = new ArithmeticProxyImpl();
14         arithmetic = new ArithmeticProxyHandle(arithmetic).getLoggingProxy();
15 
16         int result = arithmetic.add(1, 2);
17         System.out.println(result);
18         result = arithmetic.sub(3, 2);
19         System.out.println(result);
20 
21     }
22 }

控制台输出:

The method add begins with[1, 2]
The method addends with 3
3
The method sub begins with[3, 2]
The method subends with 1
1

动态代理实现前置通知 , 后置通知 , 返回通知 , 异常通知:

 1 package com.itdoc.spring.aop.proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 import java.lang.reflect.Proxy;
 6 import java.util.Arrays;
 7 
 8 /**
 9  * http://www.cnblogs.com/goodcheap
10  *
11  * @author: Wáng Chéng Dá
12  * @create: 2017-03-03 19:45
13  */
14 public class ArithmeticProxyHandle {
15 
16     //要代理的对象
17     private Arithmetic target;
18 
19     public ArithmeticProxyHandle(Arithmetic target) {
20         this.target = target;
21     }
22 
23     public ArithmeticProxyHandle() {
24     }
25 
26     public Arithmetic getLoggingProxy() {
27         Arithmetic proxy = null;
28         //代理对象由哪个类加载器负责加载
29         ClassLoader loader = target.getClass().getClassLoader();
30         //代理对象的类型, 即其中有哪些方法
31         Class [] interfaces = new Class[]{Arithmetic.class};
32         //当调用代理对象中的方法时, 执行该代码
33         InvocationHandler h = new InvocationHandler() {
34             /**
35              *
36              * @param proxy  正在返回的那个代理对象, 一般情况下, 在 invoke 方法中都不使用该对象。
37              * @param method 正在被调用的方法。
38              * @param args   调用方法时, 传入的参数。
39              * @return
40              * @throws Throwable
41              */
42             @Override
43             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
44                 String name = method.getName();
45                 Object result = null;
46                 try {
47                     //前置通知
48                     System.out.println("The method " + name + " begins with" + Arrays.asList(args));
49                     //执行方法
50                     result = method.invoke(target, args);
51                     //返回通知
52                     System.out.println("The method " + name + " ends with " + result);
53                 } catch (Exception e) {
54                     Throwable ex = new Throwable("出现异常", e);
55                     //异常通知
56                     System.out.println("The method " + name + " exception with " + ex);
57                 } finally {
58                     //后置通知
59                     System.out.println("The method " + name + " ends");
60                 }
61                 return result;
62             }
63         };
64         proxy = (Arithmetic) Proxy.newProxyInstance(loader, interfaces, h);
65         return proxy;
66     }
67 }
原文地址:https://www.cnblogs.com/chinda/p/6498421.html