缘起
最近在研读Spring AOP 的源码,在【1】的”拦截器链如何执行”小节就遇到了责任链设计模式. 其实Struts这种webmvc框架中也用到了这种设计模式.
如果想了解那部分的源码的话,可以参考【1】,这里仅仅抽象出一个小demo而已.
分析
项目工程结构如下
测试类 App.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package test;
import java.util.ArrayList; import java.util.List;
import interceptor.MethodInterceptor; import interceptor.impl.MethodInterceptorA; import interceptor.impl.MethodInterceptorB; import interceptor.impl.MethodInterceptorC; import invocation.MethodInvocation;
public class App { public static void main(String[] args) throws Throwable { Human human = new Human(); List<MethodInterceptor> chains = new ArrayList<>(); chains.add(new MethodInterceptorA()); chains.add(new MethodInterceptorB()); chains.add(new MethodInterceptorC()); MethodInvocation invocation = new MethodInvocation(human, human.getClass().getDeclaredMethod("givebirth"), chains);
invocation.proceed(); } }
|
目标类 Human.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package test;
public class Human {
public void givebirth() { System.out.println("生啦~"); } }
|
执行上下文 MethodInvocation.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| package invocation;
import java.lang.reflect.Method; import java.util.List;
import interceptor.MethodInterceptor;
public class MethodInvocation {
private Object target;
private Method method;
private Object[] args;
private List<MethodInterceptor> chains;
private int currentIndex = -1;
public MethodInvocation(Object target, Method method, List<MethodInterceptor> chains, Object... args) { this.target = target; this.method = method; this.chains = chains; this.args = args; }
public Object proceed() throws Throwable { if (currentIndex == chains.size() - 1) { return method.invoke(target, args); } MethodInterceptor interceptor = chains.get(++currentIndex); return interceptor.invoke(this); }
}
|
拦截器接口 MethodInterceptor.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package interceptor;
import invocation.MethodInvocation;
public interface MethodInterceptor {
public Object invoke(MethodInvocation mi) throws Throwable; }
|
拦截器实现类A MethodInterceptorA.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package interceptor.impl;
import interceptor.MethodInterceptor; import invocation.MethodInvocation;
public class MethodInterceptorA implements MethodInterceptor {
@Override public Object invoke(MethodInvocation mi) throws Throwable { System.out.println("护士A来处理"); return mi.proceed(); }
}
|
拦截器实现类A MethodInterceptorA.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package interceptor.impl;
import interceptor.MethodInterceptor; import invocation.MethodInvocation;
public class MethodInterceptorB implements MethodInterceptor {
@Override public Object invoke(MethodInvocation mi) throws Throwable { System.out.println("护士B来处理"); return mi.proceed(); }
}
|
拦截器实现类C MethodInterceptorC.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package interceptor.impl;
import interceptor.MethodInterceptor; import invocation.MethodInvocation;
public class MethodInterceptorC implements MethodInterceptor {
@Override public Object invoke(MethodInvocation mi) throws Throwable { System.out.println("护士C来处理"); return mi.proceed(); }
}
|
上述代码的核心就是——每个拦截器要做的业务逻辑由自己写,调用的mi.proceed()纯粹就是让chains拦截器链继续往下执行而已(因为在MethodInvocation中currentIndex会++)。
参考
【1】https://yfsyfs.github.io/2019/06/13/spring-AOP-%E6%B3%A8%E8%A7%A3%E5%8E%9F%E7%90%86/
【1】