参考链接:http://www.cnblogs.com/lcngu/p/5339555.html
Spring AOP是spring框架中除了IOC外另一个重要的技术。
问题:代码混乱,越来越多的非业务需求,如日志和验证等加入后 ,原有的业务方法急剧膨胀,每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点。
代码分散:以日志需求为例,只是为了满足这个单一的需求,就不得不在多个模块,也就是方法中多次重复相同得日志代码,如果日志需求发生变化,必须修改所有得模块。
这就需要我们需要使用一种技术来解决这种问题。
解决:使用动态代理,动态代理也就是AOP得核心思想。
日志接口:
public interface Logger { void start(Method method); void end(Method method); }
日志接口的实现类:
public class DLogger implements Logger{ @Override public void start(Method method) { System.out.println(method.getName()+"start..."); } @Override public void end(Method method) { System.out.println(method.getName()+"end..."); } }
业务接口:
public interface IHello { void sayHello(); }
业务接口实现类:
public class Hello implements IHello { @Override public void sayHello() { System.out.print("hello"); } }
动态代理类:
public class DynamicProxy implements InvocationHandler { private Object proxy; //代理类 private Object target; //目标类 public Object bind(Object proxy,Object target){ this.proxy = proxy; this.target = target; return Proxy.newProxyInstance(this.target.getClass().getClassLoader(),this.target.getClass().getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; Class clazz = this.proxy.getClass(); Method start = clazz.getDeclaredMethod("start",new Class[]{Method.class}); start.invoke(this.proxy,new Object[]{method}); method.invoke(this.target,args); Method end = clazz.getDeclaredMethod("end",new Class[]{Method.class}); end.invoke(this.proxy,new Object[]{method}); return null; } }
测试:
public class Main { public static void main(String[] args){ IHello hello = (IHello) new DynamicProxy().bind(new DLogger(),new Hello()); hello.sayHello(); } }
上述代码已经完成了一个基本的aop功能。如果我们想让指定的方法打印日志,我们只需要在invoke()方法中加一个对method名字的判断,method的名字可以写在xml文件中,这样我们就可以实现以配置文件进行解耦了。