spring recipes读书笔记--理解AOP原理
引入一个简单的数值计算器的例子,首先创建计算器接口,然后提供一个简单的实现类,在实现类中,需要对传入参数进行验证,并且进行日志记录。
package com.aop.example;public interface ArithmeticCalculator {public double add(double a,double b);public double sub(double a,double b);}package com.aop.example;import com.sun.org.apache.commons.logging.Log;import com.sun.org.apache.commons.logging.LogFactory;public class ArithmeticCalculatorImpl implements ArithmeticCalculator {private Log log=LogFactory.getLog(this.getClass());public double add(double a, double b) {// TODO Auto-generated method stublog.info("the method add() begins with "+a+","+b);validate(a);validate(b);double result = a+b;System.out.println(a+"+"+b+" = "+result);log.info("the method add() ends with "+result);return result;}public double sub(double a, double b) {// TODO Auto-generated method stublog.info("the method add() begins with "+a+","+b);validate(a);validate(b);double result = a-b;System.out.println(a+"-"+b+" = "+result);log.info("the method add() ends with "+result);return result;}private void validate(double a) {// TODO Auto-generated method stubif(a<0){throw new IllegalArgumentException("Illegal argument");}}}
package com.aop.example;public class ArithmeticCalculatorImpl implements ArithmeticCalculator {public double add(double a, double b) {// TODO Auto-generated method stubdouble result = a+b;System.out.println(a+"+"+b+" = "+result);return result;}public double sub(double a, double b) {// TODO Auto-generated method stubdouble result = a-b;System.out.println(a+"-"+b+" = "+result);return result;}}package com.aop.example;import java.lang.reflect.Method;public interface InvocationHandler {public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;}package com.aop.example;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.Arrays;import com.sun.org.apache.commons.logging.Log;import com.sun.org.apache.commons.logging.LogFactory;public class CalculatorLoggingHandler implements InvocationHandler {private Log log = LogFactory.getLog(this.getClass());private Object target;public CalculatorLoggingHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stublog.info("the method "+ method.getName()+" begins with "+Arrays.toString(args));Object result=method.invoke(target, args);log.info("the method "+method.getName()+" ends with "+result);return result;}public static Object createProxy(Object target){return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new CalculatorLoggingHandler(target));}}package com.aop.example;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class CalculatorValidationHandler implements InvocationHandler {private Object target;public CalculatorValidationHandler(Object target) {super();this.target = target;}public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stubfor(Object arg:args){validate((Double)arg);}Object result = method.invoke(target, args);return result;}private void validate(double a){if(a<0){throw new IllegalArgumentException("illegal argument");}}public static Object createProxy(Object target){return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new CalculatorLoggingHandler(target));}}
package com.aop.example;public class AopTest {public static void main(String[] args){ArithmeticCalculator arithmeticCalculatorImpl= new ArithmeticCalculatorImpl();ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) CalculatorValidationHandler.createProxy(CalculatorLoggingHandler.createProxy(arithmeticCalculatorImpl));arithmeticCalculator.add(1.0, 2.0);arithmeticCalculator.add(-2.2, 2.0);arithmeticCalculator.sub(3.0, 2.0);}}