序:最近在搞Spring MVC编程,对Spring,做了个小实验,拿出来记录一下。
先上代码:
public class LoggerExecute implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
before();
methodInvocation.proceed();
System.out.println("日志关闭:"+this.toString());
return null;
}
//前置通知
private void before(){
System.out.println("日志启动:"+this.toString());
}
}
public class BExecute implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("日志启动:"+this.toString());
System.out.println("日志关闭");;
return null;
}
}
public class Main {
public static void main(String[] args) throws Exception {
testAop();
}
private static void testAop(){
Target target=new Target();
ProxyFactory factory=new ProxyFactory();
factory.addAdvice(new LoggerExecute());
factory.addAdvice(new BExecute());
factory.addAdvice(new LoggerExecute());
factory.setTarget(new Target());
Target proxy=(Target)factory.getProxy();
proxy.execute("AOP的简单实现");
}
}
输出:
日志启动:aop.LoggerExecute@6ad5c04e
日志启动:aop.BExecute@6833ce2c
日志关闭
日志关闭:aop.LoggerExecute@6ad5c04e
结论:
对于ProxyFactory切入点的运行原理,他的处理方式是这样子的,按顺序对每个advice进行运行,在advice运行到methodInvocation.proceed();语句时,通过这条语句会跳转到下一个advice的入口,相当于暂停这个方法调用,然后调用下一个advice。循环直到最后一个advice,在最后一个advice运行methodInvocation.proceed();时调用目标方法,然后回溯运行程序,相当于如下架构:
-->
-->
-->
-->
target
<--
<--
<--
<--
如果在某个advice中没有methodInvocation.proceed();这条语句,则不会再往下调用advice直接回溯产生如下架构:
此时不会调用target,直接在没有发现这条语句的advice处开始回溯。
-->
--> (null)
| x -->
| -->
| target
| <--
| x <--
<--
<--