zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    tmp
    【ask】ghost分区还原win7出现蓝屏,试图加载CLASSPNP驱动时出现
    手动编译svn
    【ask】Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral.
    c++11小计
    入门系列-ABP CLI
    入门系列-参数验证集成
    入门系列-异常处理
    .NET Core 控制台启动失败“以一种访问权限不允许的方式做了一个访问套接字的尝试”
    入门系列-虚拟文件系统
  • 原文地址:https://www.cnblogs.com/chinda/p/6498421.html
Copyright © 2011-2022 走看看