一、AOP核心概念回顾
先明确几个关键概念:
- Joinpoint(连接点):程序执行过程中的特定点(如方法调用)
- Pointcut(切点):定义哪些连接点需要被拦截
- Advice(通知):在连接点执行的横切逻辑
- Advisor(顾问):Pointcut和Advice的组合体
- Interceptor(拦截器):实现横切逻辑的具体组件
二、适配器模式在AOP中的应用
适配器模式在Spring AOP中扮演着关键角色,主要体现在两个层面:
1. Advisor适配器
java
// 适配器模式典型实现:组合Pointcut和Advice
public class DefaultPointcutAdvisor implements Advisor {
private Pointcut pointcut;
private Advice advice;
// 构造器将两个独立组件适配为一个整体
public DefaultPointcutAdvisor(Pointcut pointcut, Advice advice) {
this.pointcut = pointcut;
this.advice = advice;
}
}
这种设计实现了:
- 解耦:Pointcut和Advice可独立变化
- 统一接口:所有Advisor都实现Advisor接口
- 灵活组合:动态组合不同的切点和通知
2. Advice适配器(框架内部)
Spring内部使用适配器将不同类型的Advice统一转换为MethodInterceptor:
java
public interface AdvisorAdapter {
// 判断是否支持特定类型的Advice
boolean supportsAdvice(Advice advice);
// 将Advice适配为MethodInterceptor
MethodInterceptor getInterceptor(Advisor advisor);
}
这种设计使框架能统一处理:
- BeforeAdvice
- AfterReturningAdvice
- ThrowsAdvice
- 自定义Advice类型
三、调用链执行机制深度解析
Spring AOP的核心执行流程通过责任链模式实现:
1. 代理对象创建
java
ProxyFactory proxyFactory = new ProxyFactory(target);
proxyFactory.addAdvisor(auditAdvisor);
proxyFactory.addAdvisor(perfAdvisor);
UserService proxy = (UserService) proxyFactory.getProxy();
此时创建的代理对象包含:
- 目标对象引用
- 按顺序排列的Advisor列表
- 代理配置信息
2. 调用链执行流程
当调用代理方法时,触发ReflectiveMethodInvocation执行:
java
public class ReflectiveMethodInvocation {
// 核心字段
protected final Object proxy;
protected final Object target;
protected final Method method;
private final Object[] arguments;
private final List<Object> 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);
}
// ...其他类型处理
}
}
3. 典型调用链执行序列
以createUser()
方法为例:
markdown
1. 审计拦截器前置处理
│
2. └──> 性能拦截器前置处理
│
3. └──> 目标方法执行
│
4. ┌── 性能拦截器后置处理(计算耗时)
│
5. └── 审计拦截器后置处理(记录结果)
这个调用栈的构建得益于责任链模式:
- 每个拦截器持有下一个处理单元的引用
- 通过
invocation.proceed()
传递控制权 - 支持动态增减拦截器
四、Pointcut匹配机制剖析
自定义Pointcut展示了精准匹配:
java
class UserMutationPointcut extends StaticMethodMatcherPointcut {
@Override
public boolean matches(Method method, Class<?> targetClass) {
// 精确匹配方法名
return method.getName().contains("create")
|| method.getName().contains("delete");
}
@Override
public ClassFilter getClassFilter() {
// 精确匹配接口类型
return clazz -> clazz == UserService.class;
}
}
Spring实际执行时采用双检查策略:
- 类级别过滤(快速失败)
- 方法级别精确匹配
五、手动模拟调用链实现
手动执行流程揭示了Spring AOP的本质:
java
void executeManually(Object target, List<Object> interceptors,
String methodName, Object[] args) {
// 1. 构建方法调用对象
CustomMethodInvocation invocation = new CustomMethodInvocation(
null, target, method, args, target.getClass(), interceptors);
// 2. 启动调用链
invocation.proceed();
}
这个模拟过程清晰展示了:
- 拦截器链的封装方式
- 当前索引的动态推进
- 目标方法的最终调用
六、设计模式综合应用分析
在Spring AOP的实现中,多种设计模式协同工作:
设计模式 | 应用场景 | 优势 |
---|---|---|
适配器模式 | 统一不同类型的Advice | 保持接口一致性 |
代理模式 | 创建目标对象的代理 | 控制对象访问 |
责任链模式 | 拦截器链执行 | 动态处理流程 |
策略模式 | Pointcut的不同匹配算法 | 灵活替换匹配策略 |
工厂模式 | 通过ProxyFactory创建代理对象 | 封装复杂创建逻辑 |
七、性能优化启示
在实际应用中需注意:
-
减少Pointcut复杂度:避免在matches()中执行重操作
-
合理排序拦截器:高频拦截器前置
-
慎用Around通知:避免嵌套过深
-
选择合适代理:
java// 显式指定代理方式 proxyFactory.setProxyTargetClass(true); // 强制CGLIB
八、总结
Spring AOP的精妙之处在于:
- 分层设计:Pointcut/Advice/Advisor各司其职
- 模式协同:适配器+责任链实现灵活扩展
- 开放扩展:支持自定义Pointcut和Interceptor
- 统一抽象:MethodInvocation封装调用上下文
流程总图

完整代码
java
package com.dwl.call_chain;
import jakarta.annotation.Nullable;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.Advisor;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.framework.ReflectiveMethodInvocation;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* 业务服务接口
*/
interface UserService {
void createUser(String username, String email);
void deleteUser(Long userId);
void getUserInfo(Long userId);
}
/**
* 业务服务实现
*/
@Slf4j
class UserServiceImpl implements UserService {
@Override
public void createUser(String username, String email) {
log.debug("[UserServiceImpl] 执行创建用户: {} ({})", username, email);
}
@Override
public void deleteUser(Long userId) {
log.debug("[UserServiceImpl] 执行删除用户: ID={}", userId);
}
@Override
public void getUserInfo(Long userId) {
log.debug("[UserServiceImpl] 获取用户信息: ID={}", userId);
}
}
/**
* 自定义切入点 - 只匹配创建和删除用户方法
* 原理:基于AOP联盟的Pointcut实现,Spring在执行时会对每个方法进行匹配检查
*/
@Slf4j
class UserMutationPointcut extends StaticMethodMatcherPointcut {
@Override
public boolean matches(Method method, @Nullable Class<?> targetClass) {
// 只匹配包含"create"或"delete"的方法名
boolean isMatch = method.getName().contains("create") || method.getName().contains("delete");
log.debug("[UserMutationPointcut] 方法匹配检查: {} - 结果: {}", method.getName(), isMatch);
return isMatch;
}
@Override
@NonNull
public ClassFilter getClassFilter() {
// 限定只对UserService接口生效
return clazz -> {
boolean match = clazz == UserService.class;
log.debug("[UserMutationPointcut] 类匹配检查: {} - 结果: {}", clazz.getSimpleName(), match);
return match;
};
}
}
/**
* 自定义切入点 - 匹配所有方法
*/
@Slf4j
class AllMethodsPointcut extends StaticMethodMatcherPointcut {
@Override
public boolean matches(@NonNull Method method, @NonNull Class<?> targetClass) {
log.debug("[AllMethodsPointcut] 匹配所有方法: {}", method.getName());
return true; // 无条件匹配所有方法
}
}
/**
* 审计拦截器 - 用于关键业务操作
* 实现AOP联盟的MethodInterceptor接口
* 原理:作为Advice被织入到连接点(join point)
*/
@Slf4j
class AuditInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
String methodName = invocation.getMethod().getName();
Object[] args = invocation.getArguments();
log.debug("[审计拦截器] >>> 进入审计处理, 方法: {}", methodName);
System.out.println("=== AUDIT START: " + methodName + " ===");
System.out.println("| User: admin@example.com");
System.out.println("| Args: " + java.util.Arrays.toString(args));
// 重要:调用拦截器链中的下一个处理器
log.debug("[审计拦截器] 执行proceed(), 进入下一个拦截器或目标方法");
Object result = invocation.proceed();
System.out.println("| Result: " + result);
System.out.println("=== AUDIT END ===");
log.debug("[审计拦截器] <<< 退出审计处理, 方法: {}", methodName);
return result;
}
}
/**
* 性能监控拦截器 - 用于所有方法
* 原理:通过计算执行时间实现性能监控
*/
@Slf4j
class PerformanceInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
long startTime = System.currentTimeMillis();
String methodName = invocation.getMethod().getName();
log.debug("[性能拦截器] >>> 开始执行计时, 方法: {}", methodName);
// 重要:触发后续调用链(可能是其他拦截器或目标方法)
Object result = invocation.proceed();
long duration = System.currentTimeMillis() - startTime;
log.debug("[性能拦截器] 方法执行完成, 耗时: {}ms", duration);
System.out.println("[Perf] " + methodName + " executed in " + duration + "ms");
log.debug("[性能拦截器] <<< 退出性能监控处理");
return result;
}
}
/**
* 自定义的ReflectiveMethodInvocation子类
* 原理:Spring AOP核心调用处理器,管理拦截器链的执行顺序
* <p>
* 关键机制:
* 1. 维护拦截器列表的当前位置
* 2. proceed()方法驱动调用链前进
* 3. 当所有拦截器执行完毕后调用目标方法
*/
@Slf4j
class CustomMethodInvocation extends ReflectiveMethodInvocation {
public CustomMethodInvocation(Object proxy, Object target, Method method, Object[] args,
Class<?> targetClass, List<Object> interceptors) {
super(proxy, target, method, args, targetClass, interceptors);
log.debug("创建自定义方法调用处理器 | 目标类: {} | 方法: {} | 拦截器数量: {}",
targetClass.getSimpleName(), method.getName(), interceptors.size());
}
}
/**
* 核心流程:
* 1. 创建目标对象(被代理对象)
* 2. 创建切点(Pointcut)和通知(Advice)
* 3. 通过Advisor将切点和通知关联
* 4. 使用ProxyFactory创建代理对象:
* - 默认使用JDK动态代理(针对接口)
* - 无接口时使用CGLIB代理
* 5. 拦截器链执行机制:
* - 创建MethodInvocation对象
* - 按顺序执行拦截器
* - 最后执行目标方法
*
* @ClassName SpringAopWithAdvisorDemo
* @Description
* @Version 1.0.0
* @Date 2025
* @Author By Dwl
*/
@Slf4j
public class SpringAopWithAdvisorDemo {
public static void main(String[] args) throws Throwable {
log.debug("===== Spring AOP 底层原理演示 =====");
// 创建目标对象(实际业务实现)
UserService target = new UserServiceImpl();
log.debug("创建目标对象: {}", target.getClass().getName());
// ============= 创建Advisor =============
// Advisor 1: 审计顾问 (仅作用于变更操作)
Pointcut mutationPointcut = new UserMutationPointcut();
Advice auditAdvice = new AuditInterceptor();
Advisor auditAdvisor = new DefaultPointcutAdvisor(mutationPointcut, auditAdvice);
log.debug("创建审计Advisor | 切点: {} | 通知: {}",
mutationPointcut.getClass().getSimpleName(), auditAdvice.getClass().getSimpleName());
// Advisor 2: 性能顾问 (作用于所有方法)
Pointcut allMethodsPointcut = new AllMethodsPointcut();
Advice perfAdvice = new PerformanceInterceptor();
Advisor perfAdvisor = new DefaultPointcutAdvisor(allMethodsPointcut, perfAdvice);
log.debug("创建性能Advisor | 切点: {} | 通知: {}",
allMethodsPointcut.getClass().getSimpleName(), perfAdvice.getClass().getSimpleName());
// ==================== 方式1: 标准Spring代理 ====================
log.debug("\n========= 创建Spring代理 =========");
ProxyFactory proxyFactory = new ProxyFactory(target);
proxyFactory.addInterface(UserService.class);
proxyFactory.addAdvisor(auditAdvisor);
proxyFactory.addAdvisor(perfAdvisor);
log.debug("代理工厂配置 | 代理接口: {} | Advisor数量: {}",
UserService.class.getSimpleName(), proxyFactory.getAdvisors().length);
UserService proxy = (UserService) proxyFactory.getProxy();
log.debug("代理创建完成 | 代理类: {}", proxy.getClass().getName());
log.debug("代理技术: {}", proxyFactory.getProxy().toString().contains("$Proxy")
? "JDK动态代理" : "CGLIB");
// 通过代理对象执行方法
log.debug("\n>>>>>> 执行 createUser <<<<<<");
proxy.createUser("john_doe", "john@example.com");
log.debug("\n>>>>>> 执行 deleteUser <<<<<<");
proxy.deleteUser(123L);
log.debug("\n>>>>>> 执行 getUserInfo <<<<<<");
proxy.getUserInfo(456L);
log.debug("\n");
// ==================== 方式2: 手动创建调用链 ====================
log.debug("========= 手动创建调用链 (模拟Spring执行过程) =========");
// 获取所有拦截器(通过Advisor获取)
List<Object> interceptors = new ArrayList<>();
for (Advisor advisor : proxyFactory.getAdvisors()) {
interceptors.add(advisor.getAdvice());
}
log.debug("收集到拦截器: {} 个", interceptors.size());
interceptors.forEach(interceptor ->
log.debug(" - 拦截器: {}", interceptor.getClass().getSimpleName()));
// 测试方法1: createUser (会触发所有拦截器)
log.debug("\n--- 手动执行 createUser ---");
executeManually(target, interceptors, "createUser", new Object[]{"test_user", "test@example.com"});
// 测试方法2: getUserInfo (只会触发性能拦截器)
log.debug("\n--- 手动执行 getUserInfo ---");
executeManually(target, interceptors, "getUserInfo", new Object[]{789L});
}
/**
* 手动执行方法调用流程
* 模拟Spring代理的核心执行过程:
* 1. 创建ReflectiveMethodInvocation对象
* 2. 调用proceed()启动拦截器链
* 3. 调用链依次执行:
* - 按顺序执行所有MethodInterceptor
* - 最后执行目标方法
*/
private static void executeManually(Object target, List<Object> interceptors,
String methodName, Object[] args) throws Throwable {
// 获取方法对象
Class<?>[] paramTypes = getParameterTypes(args);
log.debug("获取方法元数据 | 方法名: {} | 参数类型: {}", methodName, paramTypes);
Method method = UserService.class.getMethod(methodName, paramTypes);
// 创建自定义方法调用处理器(核心)
CustomMethodInvocation invocation = new CustomMethodInvocation(
null, // 代理对象(手动调用不需要)
target, // 目标对象
method, // 目标方法
args, // 方法参数
target.getClass(), // 目标类
interceptors // 拦截器链
);
// 核心:启动拦截器链执行(模拟Spring代理的invoke方法)
log.debug(">>>>>> 启动拦截器链执行");
invocation.proceed();
log.debug("<<<<<< 拦截器链执行完成");
}
private static Class<?>[] getParameterTypes(Object[] args) {
Class<?>[] paramTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
paramTypes[i] = args[i].getClass();
log.debug("参数类型检测 | 参数[{}]: {}", i, paramTypes[i].getSimpleName());
}
return paramTypes;
}
}