前言
本文涉及到适配模式的基本用法,以及在Spring AOP中如何使用,首先需要了解适配模式的工作原理,然后结合Spring AOP的具体实现来详细详细解析源码。
首先,适配模式,也就是Adapter Pattern,属于结构型设计模式,主要用于让不兼容的接口能够一起工作。要了解它的定义、结构、应用场景以及优缺点。然后,可能需要一个具体的例子来说明,比如电压适配器,这样用户更容易理解。
接下来是Spring AOP中的拦截器链。如果对AOP的概念有一定了解,但想深入知道拦截器链是如何通过适配模式实现的。这里需要分析Spring AOP的源码,特别是MethodInterceptor接口和AdvisorAdapter的作用。需要提到具体的类,比如MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter和ThrowsAdviceAdapter,以及它们如何将不同类型的Advice适配成统一的MethodInterceptor。
实际开发中遇到需要整合不同接口的情况,或者在使用Spring AOP时想自定义拦截器,了解底层实现有助于调试和扩展。
总结来说,回答需要分为两部分:适配模式的讲解和Spring AOP拦截器链的源码分析。结合理论、示例和源码。
一、适配模式(Adapter Pattern)解析
适配模式是一种 结构型设计模式,用于将不兼容的接口转换为客户端期望的接口,使原本无法协同工作的类能够一起工作。其核心思想是 通过一个中间层(适配器)解决接口不匹配问题。
1. 适配模式的结构
角色 | 描述 |
---|---|
目标接口 | 客户端期望的接口(如 Target )。 |
被适配者 | 需要被适配的现有类(如 Adaptee )。 |
适配器 | 实现目标接口,并持有被适配者的引用,转换调用逻辑(如 Adapter )。 |
2. 适配模式示例
场景:将电压 220V 转换为 5V(USB 充电器即为适配器)。
// 目标接口:期望的5V电压
interface Voltage5V {int output5V();
}// 被适配者:现有的220V电源
class Voltage220V {public int output220V() {return 220;}
}// 适配器:将220V转换为5V
class VoltageAdapter implements Voltage5V {private Voltage220V voltage220V;public VoltageAdapter(Voltage220V voltage220V) {this.voltage220V = voltage220V;}@Overridepublic int output5V() {int src = voltage220V.output220V();return src / 44; // 转换为5V}
}// 客户端使用
public class Client {public static void main(String[] args) {Voltage5V adapter = new VoltageAdapter(new Voltage220V());System.out.println(adapter.output5V()); // 输出5}
}
3. 适配模式的类型
- 类适配器:通过继承被适配者实现(需支持多继承,Java中不适用)。
- 对象适配器:通过组合被适配者实现(推荐方式)。
4. 适配模式的优缺点
- 优点:
- 解耦客户端与被适配者。
- 符合开闭原则,无需修改现有代码。
- 缺点:
- 过度使用可能导致系统复杂化。
5. 应用场景
- 整合遗留代码或第三方库。
- 统一多个类的接口(如日志框架适配)。
二、Spring AOP 拦截器链的源码解析
Spring AOP 的拦截器链(Interceptor Chain)基于 责任链模式,但其底层实现中大量使用了 适配模式,将不同类型的通知(Advice)适配为统一的 MethodInterceptor
。
1. Spring AOP 核心接口
接口 | 作用 |
---|---|
MethodInterceptor | 方法拦截器,在方法调用前后执行逻辑(AOP Alliance 标准接口)。 |
Advice | 通知的标记接口(如 BeforeAdvice 、AfterReturningAdvice )。 |
Advisor | 组合 Advice 和切点(Pointcut),确定在何处应用通知。 |
2. 适配模式在拦截器链中的应用
Spring 通过 适配器(AdvisorAdapter) 将不同类型的 Advice
转换为 MethodInterceptor
,以便统一执行。
源码示例:AdvisorAdapter
实现类
Spring 内置三种适配器,对应不同类型的通知:
MethodBeforeAdviceAdapter
:将MethodBeforeAdvice
适配为MethodInterceptor
。AfterReturningAdviceAdapter
:将AfterReturningAdvice
适配为MethodInterceptor
。ThrowsAdviceAdapter
:将ThrowsAdvice
适配为MethodInterceptor
。
以 MethodBeforeAdviceAdapter
为例:
class MethodBeforeAdviceAdapter implements AdvisorAdapter {@Overridepublic boolean supportsAdvice(Advice advice) {return (advice instanceof MethodBeforeAdvice);}@Overridepublic MethodInterceptor getInterceptor(Advisor advisor) {MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();return new MethodBeforeAdviceInterceptor(advice);}
}
拦截器链的构建流程
- 创建代理对象:通过
ProxyFactory
创建目标对象的代理。 - 获取所有 Advisor:根据切面配置,筛选匹配的 Advisor。
- 适配为拦截器:调用
AdvisorAdapterRegistry
将 Advisor 中的Advice
转换为MethodInterceptor
。 - 排序拦截器:按优先级排序拦截器,形成调用链。
源码入口:DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice()
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(AdvisorChainFactory config, Method method, Class<?> targetClass) {List<Object> interceptorList = new ArrayList<>();for (Advisor advisor : config.getAdvisors()) {if (advisor instanceof PointcutAdvisor) {// 检查切点是否匹配方法if (((PointcutAdvisor) advisor).getPointcut().getMethodMatcher().matches(method, targetClass)) {// 通过适配器转换为 MethodInterceptorMethodInterceptor[] interceptors = config.getInterceptors(advisor);interceptorList.addAll(Arrays.asList(interceptors));}}}return interceptorList;
}
3. 拦截器链的执行流程
拦截器链的执行通过 ReflectiveMethodInvocation
实现,采用 递归调用模式。
源码示例:ReflectiveMethodInvocation.proceed()
public class ReflectiveMethodInvocation implements ProxyMethodInvocation {private final List<?> interceptorsAndDynamicMethodMatchers;private int currentInterceptorIndex = -1;public Object proceed() throws Throwable {// 所有拦截器执行完毕,调用原始方法if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint();}// 获取下一个拦截器并执行Object interceptor = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);if (interceptor instanceof MethodInterceptor) {MethodInterceptor mi = (MethodInterceptor) interceptor;return mi.invoke(this);}// ...}
}
4. 示例:拦截器链的执行顺序
假设存在以下拦截器:
- Before Advice:方法执行前打印日志。
- Around Advice:计算方法执行时间。
- After Advice:方法执行后清理资源。
调用流程:
┌→ BeforeAdviceInterceptor
│ ┌→ AroundAdviceInterceptor.proceed()
│ │ ┌→ 目标方法执行
│ │ └→ AroundAdviceInterceptor 计算耗时
│ └→ AfterAdviceInterceptor
└─ 返回结果
三、总结
设计模式 | 在 Spring AOP 中的应用 |
---|---|
适配模式 | 将不同类型的 Advice 转换为统一的 MethodInterceptor 。 |
责任链模式 | 拦截器链按顺序执行,每个拦截器决定是否传递调用。 |
源码核心类:
AdvisorAdapter
:适配Advice
为MethodInterceptor
。ReflectiveMethodInvocation
:递归执行拦截器链。ProxyFactory
:创建代理对象并管理拦截器。
通过适配模式,Spring AOP 实现了对多种通知类型的统一处理,而拦截器链机制则确保了切面逻辑的灵活组合与执行。这一设计充分体现了 高内聚、低耦合 的架构思想。