SpringAOP 的整体涉及是递归方式 +责任链设计模式
下面我们通过模拟Spring 源码方式 看下如何调用的
/** * 调用链接口 */ public interface MethodInterceptor { Object invoke(MethodInvocation invocation) throws Throwable; }
/** * 前置通知接口 */ public class MethodBeforeAdviceInterceptor implements MethodInterceptor{ public Object invoke(MethodInvocation mi) throws Throwable { System.out.println("前置通知"); return mi.proceed(); } }
/** * 环绕通知接口 */ public class AspectJAroundAdvice implements MethodInterceptor{ public Object invoke(MethodInvocation mi) throws Throwable { System.out.println("环绕通知前"); mi.proceed(); System.out.println("环绕通知后"); return null; } }
/** * 后置通知接口 */ public class AspectJAfterAdvice implements MethodInterceptor{ public Object invoke(MethodInvocation mi) throws Throwable { try { return mi.proceed();//注意这里因为是后置通知,先递归 完了之后在后置通知,即 先执行目标原方法,在回来 执行后置 } finally { System.out.println("后置通知"); } } }
public interface Joinpoint { Object proceed() throws Throwable; }
import java.lang.reflect.Method; public interface MethodInvocation extends Joinpoint { Method getMethod(); }
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.List; public class ReflectiveMethodInvocation implements MethodInvocation { protected Object proxy; @Nullable private Object target; private Method method; protected Object[] arguments; @Nullable private Class<?> targetClass; protected List<?> interceptorsAndDynamicMethodMatchers; private int currentInterceptorIndex = -1; @Override public Method getMethod() { return null; } protected ReflectiveMethodInvocation(List<Object> interceptorsAndDynamicMethodMatchers,Method method,Object target,Object[] arguments) { this.proxy = proxy; this.target = target; this.targetClass = targetClass; this.method=method; this.arguments=arguments; this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers; } @Override public Object proceed() throws Throwable { if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return this.invokeJoinpoint(); } Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } private Object invokeJoinpoint() { try { return method.invoke(this.target, this.arguments) ; } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } }
测试类:
public static void main(String[] args) { List<Object> list =new ArrayList<>(); list.add(new MethodBeforeAdviceInterceptor()); list.add(new AspectJAfterAdvice()); list.add(new AspectJAroundAdvice()); try { Method method =OrderService.class.getMethod("add",String.class); Object[] objects = {"AOP Test 参数"}; new ReflectiveMethodInvocation(list,method,new OrderService(),objects).proceed(); } catch (Throwable throwable) { throwable.printStackTrace(); } } 控制台打印的信息: 前置通知 环绕通知前 add 方法运行中。。。。AOP Test 参数 环绕通知后 后置通知