Spring入门学习(AOP) 第十四节

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011171125/article/details/85797705

为什么需要AOP

  1. 新建一个接口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;
    	}
    
    }
    
    在上述类中,当我们需要为这些类添加日志时,需要在相应的业务逻辑中取添加,要修改时,可能也会涉及许多改动的地方。
    在这里插入图片描述

一种方法是使用动态代理解决

在这里插入图片描述

  1. 新建一个代理类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;
    	}
    }
    
  2. 我们注释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注解声明切面
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/u011171125/article/details/85797705