版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011171125/article/details/85797705
Spring入门学习(AOP)
为什么需要AOP
- 新建一个接口
ArithmeticCalculator.java
和它的实现类ArithmeticCalculatorImpl
在上述类中,当我们需要为这些类添加日志时,需要在相应的业务逻辑中取添加,要修改时,可能也会涉及许多改动的地方。public interface ArithmeticCalculator { int add(int i, int j); int sub(int i, int j); int mul(int i, int j); int div(int i, int j); } public class ArithmeticCalculatorImpl implements ArithmeticCalculator { @Override public int add(int i, int j) { System.out.println("The method add begins with["+i+","+j+"]"); int result = i + j; System.out.println("The method add ends with "+ result); return result; } @Override public int sub(int i, int j) { System.out.println("The method sub begins with["+i+","+j+"]"); int result = i - j; System.out.println("The method sub ends with "+ result); return result; } @Override public int mul(int i, int j) { System.out.println("The method mul begins with["+i+","+j+"]"); int result = i * j; System.out.println("The method mul ends with "+ result); return result; } @Override public int div(int i, int j) { System.out.println("The method div begins with["+i+","+j+"]"); int result = i / j; System.out.println("The method div ends with "+ result); return result; } }
一种方法是使用动态代理解决
- 新建一个代理类
ArithmeticCalculatorLoggingProxy
使用反射可以在方法执行前后做一些事,比如获取方法名添加日志处理,最后返回代理类。public class ArithmeticCalculatorLoggingProxy { // 要代理的对象 private ArithmeticCalculator target; public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) { this.target = target; } public ArithmeticCalculator getLoggingProxy() { ArithmeticCalculator proxy = null; // 代理对象由哪一个类加载器负责加载 ClassLoader loader = target.getClass().getClassLoader(); Class[] interfaces = new Class[]{ArithmeticCalculator.class}; // 当调用代理对象提供的方法时,该执行的代码 InvocationHandler h = new InvocationHandler() { /** * proxy: 正在返回的代理对象,一般情况下,在invoke方法中不使用该对象 * method: 正在被调用的方法 * args: 调用方法时,传入的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 一般在内部是不会使用proxy对象(自己调用自己了) // System.out.println(proxy.toString()); String methodName = method.getName(); // 日志 System.out.println("the Methdo:"+methodName+"Begins with: "+Arrays.asList(args)); // 执行方法 Object result = method.invoke(target, args); System.out.println("The method "+methodName+"ends with "+result); return result; } }; proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h); return proxy; } }
- 我们注释
ArithmeticCalculatorImpl
类方法中打印的信息,创建测试方法,使用代理类添加日志信息:
测试结果:public class Main { public static void main(String[] args) { ArithmeticCalculator target = new ArithmeticCalculatorImpl(); ArithmeticCalculator proxy = new ArithmeticCalculatorLoggingProxy(target).getLoggingProxy(); int result = proxy.add(2, 1); System.out.println("-->" + result); result = proxy.div(4, 2); System.out.println("-->" + result); } }
the Methdo:addBegins with: [2, 1] The method addends with 3 -->3 the Methdo:divBegins with: [4, 2] The method divends with 2 -->2
使用Spring AOP
AOP简介
AOP术语
可以使用@AspectJ
注解声明切面