其实就是AOP作用就是:把分散在各个地方的功能分离出来形成组件。这样理解起来非常抽象;
看如下代码,ArithmeticCaculatorImpl 实现了ArithmeticCaculator,也就是一个实现计算加、减、乘、除的一个功能;此时如果想在每个方法得到结果之前,插入日志,表示方法开启,计算完成之后,添加日志表示计算完成该如何实现。可以在每个方法的计算语句前后加上打印日志;
1 public interface ArithmeticCaculator { 2 3 int add(int i,int j); 4 int sub(int i,int j); 5 6 int mul(int i,int j); 7 int div(int i,int j); 8 9 10 }
1 public class ArithmeticCaculatorImpl implements ArithmeticCaculator { 2 3 @Override 4 public int add(int i, int j) { 5 int result = i+j; 6 return result; 7 } 8 9 @Override 10 public int sub(int i, int j) { 11 int result = i-j; 12 return result; 13 } 14 15 @Override 16 public int mul(int i, int j) { 17 int result = i*j; 18 return result; 19 } 20 21 @Override 22 public int div(int i, int j) { 23 int result = i/j; 24 return result; 25 } 26 27 }
可以在每个方法的计算语句前后加上打印日志的解决方式。代码如下;
1 public class ArithmeticCaculatorImpl implements ArithmeticCaculator { 2 3 @Override 4 public int add(int i, int j) { 5 System.out.println("the method add begins with["+i+"+"+j+"]"); 6 int result = i+j; 7 System.out.println("the method add begins with "+result); 8 return result; 9 } 10 11 @Override 12 public int sub(int i, int j) { 13 System.out.println("the method add begins with["+i+"-"+j+"]"); 14 int result = i-j; 15 System.out.println("the method add begins with "+result); 16 return result; 17 } 18 19 @Override 20 public int mul(int i, int j) { 21 System.out.println("the method add begins with["+i+"*"+j+"]"); 22 int result = i*j; 23 System.out.println("the method add begins with "+result); 24 return result; 25 } 26 27 @Override 28 public int div(int i, int j) { 29 System.out.println("the method add begins with["+i+"/"+j+"]"); 30 int result = i/j; 31 System.out.println("the method add begins with "+result); 32 return result; 33 } 34 35 }View Code
这种解决方式,维护起来非常麻烦;每添加一个计算方法(比如添加一个取模方法,就得加上对应的日志);还有一种办法就是,采用动态代理
1.添加代理工厂:
1 package lixiuming.spring.aop.helloworld; 2 3 import java.lang.reflect.Proxy; 4 5 public class ProxyFactory { 6 7 // 调用此方法,返回一个代理类的对象,解决了问题一 8 public static Object getProxyInstance(Object obj) {// obj为被代理类的对象 9 ProxyHandler proxyHandler = new ProxyHandler(); 10 proxyHandler.bind(obj);; 11 return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), proxyHandler); 12 } 13 }
2.绑定代理类
1 package lixiuming.spring.aop.helloworld; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.util.Arrays; 6 7 public class ProxyHandler implements InvocationHandler { 8 9 private Object obj; 10 11 public void bind(Object obj) { 12 this.obj = obj; 13 } 14 15 @Override 16 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 17 // TODO Auto-generated method stub 18 19 String methodName = method.getName(); 20 System.out.println("the method " + methodName + "begins with" + Arrays.asList(args)); 21 Object result = method.invoke(obj, args); 22 System.out.println("the method " + methodName + "begins with" + result); 23 return method.invoke(obj, args); 24 } 25 26 }
测试:
1 public static void main(String[] args) { 2 3 ArithmeticCaculator arithmeticCaculator1 = (ArithmeticCaculator) ProxyFactory 4 .getProxyInstance(new ArithmeticCaculatorImpl()); 5 int result11 = arithmeticCaculator1.add(1, 2); 6 System.out.println("-->" + result11); 7 8 int result22 = arithmeticCaculator1.div(4, 2); 9 System.out.println("-->" + result22); 10 11 int result33 = arithmeticCaculator1.mul(4, 2); 12 System.out.println("-->" + result33); 13 14 int result44 = arithmeticCaculator1.sub(4, 2); 15 System.out.println("-->" + result44); 16 17 }
运行结果:
the method addbegins with[1, 2]
the method addbegins with3
-->3
the method divbegins with[4, 2]
the method divbegins with2
-->2
the method mulbegins with[4, 2]
the method mulbegins with8
-->8
the method subbegins with[4, 2]
the method subbegins with2
-->2
这个运行结果和 在每个方法的计算语句前后加上打印日志的解决方式 结果一样;但是配置还是不是那么灵活(比如想配置某个包下面的所有方法,都需要执行日志,那么每次调用该方法的动态代理等问题没有很好的解决)。spring提供了aop方式的解决方案;
实现代码放在下一篇三(二)、AOP配置中