责任链模式原理详解和源码实例以及SpringAOP拦截器链的执行源码如何使用责任链模式?
- 软件开发
- 2025-08-25 18:12:01

前言
本文首先介绍了责任链的基本原理,并附带一个例子说明责任链模式,确保能够理解责任链的前提下,在进行Spring AOP执行责任链的源码分析。责任链模式允许将多个处理对象连接成链,请求沿着链传递,直到被处理或结束。每个处理者可以选择处理请求或传递给下一个。
Spring AOP的拦截器链,拦截器或者过滤器链,都是典型的责任链应用。比如,当一个方法被调用时,多个拦截器按顺序执行,每个拦截器可以决定是否继续执行链中的下一个。
深入Spring AOP的源码部分,特别是拦截器链的执行过程。比如,在Spring AOP中,当调用一个被增强的方法时,会创建一个MethodInvocation对象,其中包含拦截器链。每个拦截器都是一个Advice,比如MethodInterceptor。这时候,责任链模式的应用可能体现在拦截器的依次调用上,每个拦截器处理完后调用下一个,直到最后一个拦截器执行实际的方法。
具体分析Spring的源码,比如ReflectiveMethodInvocation类的proceed方法。这个方法可能负责按顺序调用拦截器链中的每个拦截器,直到所有拦截器处理完毕,最后调用目标方法。这个流程是否符合责任链模式的结构?是的,每个拦截器处理请求,并决定是否传递下去。
可能还需要比较责任链模式的不同变体,比如纯的责任链(每个处理者必须处理请求)和不纯的(可以传递)。Spring AOP的拦截器链属于后者,每个拦截器都可以选择是否继续传递,或者在处理前后执行某些操作,然后继续传递。
另外,Spring AOP的基本原理不在本文中介绍了,详情请看以往文章,有更加详细的表述,有理论和源码的解析。文章:Spring AOP源码解析
实际应用场景本文也涉及到,如何自定义拦截器,如何调整拦截器链的顺序,或者如何利用责任链模式实现类似的功能。这些实际应用案例可以增强回答的实用性。
最后,确保回答结构清晰,先解释责任链模式,再结合Spring源码详细说明,最后总结其优势和应用场景。需要避免过于冗长的代码分析,而是突出重点部分,比如关键类和方法的调用流程。
责任链模式原理详解与源码实例
一、责任链模式(Chain of Responsibility Pattern)原理
核心思想:将多个处理对象连成一条链,请求沿链传递,直到有一个处理对象处理它或链结束。每个处理对象可选择处理请求或传递给下一个对象。
1. 模式结构 角色职责Handler(抽象处理者)定义处理请求的接口,通常包含指向下一个处理者的引用(nextHandler)。ConcreteHandler具体处理者,实现处理逻辑,或决定是否将请求传递到下一个处理者。Request请求对象,封装请求的上下文数据。 2. 类图 +----------------+ +-------------------+ | Handler | <|-------| ConcreteHandlerA | +----------------+ +-------------------+ | +nextHandler | | +handleRequest() | | +handleRequest()| +-------------------+ +----------------+ ^ | | | | +-------------------+ | ConcreteHandlerB | +-------------------+ | +handleRequest() | +-------------------+ 3. 执行流程 客户端将请求发送到责任链的第一个处理者。每个处理者决定是否处理该请求: 若处理,则终止传递。若不处理,则调用 nextHandler.handleRequest()。 请求沿链传递,直到被处理或链结束。二、责任链模式源码实例 1. 抽象处理者(Handler) public abstract class Handler { protected Handler nextHandler; // 指向下一个处理者 public void setNextHandler(Handler nextHandler) { this.nextHandler = nextHandler; } public abstract void handleRequest(Request request); } 2. 具体处理者(ConcreteHandler) public class ConcreteHandlerA extends Handler { @Override public void handleRequest(Request request) { if (canHandle(request)) { System.out.println("ConcreteHandlerA 处理请求: " + request.getData()); } else if (nextHandler != null) { nextHandler.handleRequest(request); // 传递给下一个处理者 } } private boolean canHandle(Request request) { return request.getType().equals("A"); } } public class ConcreteHandlerB extends Handler { @Override public void handleRequest(Request request) { if (canHandle(request)) { System.out.println("ConcreteHandlerB 处理请求: " + request.getData()); } else if (nextHandler != null) { nextHandler.handleRequest(request); // 传递给下一个处理者 } } private boolean canHandle(Request request) { return request.getType().equals("B"); } } 3. 请求对象(Request) public class Request { private String type; // 请求类型 private String data; // 请求数据 public Request(String type, String data) { this.type = type; this.data = data; } public String getType() { return type; } public String getData() { return data; } } 4. 客户端调用 public class Client { public static void main(String[] args) { // 创建责任链 Handler handlerA = new ConcreteHandlerA(); Handler handlerB = new ConcreteHandlerB(); handlerA.setNextHandler(handlerB); // 发送请求 Request request1 = new Request("A", "请求1"); Request request2 = new Request("B", "请求2"); handlerA.handleRequest(request1); // 由 ConcreteHandlerA 处理 handlerA.handleRequest(request2); // 由 ConcreteHandlerB 处理 } }
输出结果:
ConcreteHandlerA 处理请求: 请求1 ConcreteHandlerB 处理请求: 请求2三、Spring AOP 拦截器链中的责任链模式
Spring AOP 通过 拦截器链(Interceptor Chain) 实现方法增强(如事务、日志),其核心设计正是基于责任链模式。
1. 核心组件 组件职责MethodInvocation封装被代理方法的调用上下文(类似 Request)。MethodInterceptor拦截器接口(类似 Handler),定义增强逻辑。ReflectiveMethodInvocation具体责任链实现,管理拦截器链的调用顺序。 2. 源码解析 (1)拦截器链的创建在生成代理对象时,Spring 会将所有匹配的拦截器(如 MethodInterceptor)按顺序组合成链。
入口:AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) { // 获取所有拦截器(包括事务、日志等) List<Object> interceptorList = new ArrayList<>(); for (Advisor advisor : this.advisors) { if (advisor instanceof PointcutAdvisor) { // 匹配拦截器是否适用于当前方法 if (((PointcutAdvisor) advisor).getPointcut().getMethodMatcher().matches(method, targetClass)) { interceptorList.add(advisor.getAdvice()); } } } return interceptorList; } (2)责任链的触发代理对象调用方法时,触发 ReflectiveMethodInvocation#proceed(),按顺序执行拦截器链。该方法类似于递归执行,递归方法也是有终止条件的,请注意区分。
源码:ReflectiveMethodInvocation
public class ReflectiveMethodInvocation implements ProxyMethodInvocation { private final Object target; // 目标对象 private final Method method; // 目标方法 private final Object[] arguments; // 方法参数 private final List<Object> interceptorsAndDynamicMethodMatchers; // 拦截器链 private int currentInterceptorIndex = -1; // 当前拦截器索引 public Object proceed() throws Throwable { // 1. 所有拦截器执行完毕,调用原始方法 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } // 2. 获取下一个拦截器 Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); // 3. 执行拦截器逻辑 if (interceptorOrInterceptionAdvice instanceof MethodInterceptor) { MethodInterceptor mi = (MethodInterceptor) interceptorOrInterceptionAdvice; return mi.invoke(this); // 将当前 MethodInvocation 传递给拦截器 } else { // 动态匹配器处理(略) } } // 调用原始方法 protected Object invokeJoinpoint() throws Throwable { return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments); } } (3)拦截器的执行逻辑每个 MethodInterceptor 拦截器决定是否继续传递链(调用 proceed())或终止。
示例:Spring 事务拦截器 TransactionInterceptor
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { // 1. 开启事务 TransactionInfo txInfo = createTransactionIfNecessary(invocation.getMethod(), targetClass); try { // 2. 继续执行拦截器链(责任链传递) Object retVal = invocation.proceed(); // 3. 提交事务 commitTransactionAfterReturning(txInfo); return retVal; } catch (Throwable ex) { // 4. 回滚事务 completeTransactionAfterThrowing(txInfo, ex); throw ex; } } }四、责任链模式在 Spring AOP 中的设计优势
灵活扩展 新增拦截器只需实现 MethodInterceptor 并注册到链中,无需修改现有代码。
逻辑解耦 每个拦截器专注单一职责(如事务、日志),通过链式调用组合功能。
动态控制流程 拦截器可决定是否继续调用链(如权限校验失败时直接抛出异常终止流程)。
执行顺序可控 拦截器链的顺序可通过 @Order 注解或实现 Ordered 接口调整。
五、实际应用场景与自定义拦截器 1. 自定义拦截器示例 public class LoggingInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("方法调用前: " + invocation.getMethod().getName()); Object result = invocation.proceed(); // 继续链 System.out.println("方法调用后: " + invocation.getMethod().getName()); return result; } } 2. 配置拦截器链
在 Spring 配置中注册拦截器:
<bean id="loggingInterceptor" class="com.example.LoggingInterceptor"/> <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"/> <aop:config> <aop:advisor advice-ref="loggingInterceptor" order="1"/> <aop:advisor advice-ref="transactionInterceptor" order="2"/> </aop:config> 3. 执行顺序拦截器按 order 值从小到大依次执行:
LoggingInterceptor(前置日志) → TransactionInterceptor(事务管理) → 目标方法六、总结 责任链模式核心:解耦请求发送者与处理者,允许多个对象按链式处理请求。Spring AOP 实现:通过 ReflectiveMethodInvocation 管理拦截器链,每个 MethodInterceptor 按责任链模式依次执行。优势:灵活扩展、职责分离、动态流程控制。应用场景:事务管理、日志记录、权限校验、性能监控等切面功能。
责任链模式原理详解和源码实例以及SpringAOP拦截器链的执行源码如何使用责任链模式?由讯客互联软件开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“责任链模式原理详解和源码实例以及SpringAOP拦截器链的执行源码如何使用责任链模式?”
上一篇
SpringDI