一、核心架构分析
1. Spring AOP核心组件
classDiagram
class AnnotationAwareAspectJAutoProxyCreator {
+ postProcessAfterInitialization()
+ getAdvicesAndAdvisorsForBean()
}
class ProxyFactory {
+ target : Object
+ advisors : List
+ getProxy()
+ getInterceptorsAndDynamicInterceptionAdvice()
}
class Advisor {
<>
+ getAdvice()
+ isPerInstance()
}
class AspectJPointcutAdvisor {
- advice : Advice
- pointcut : Pointcut
+ matches()
}
class ReflectiveMethodInvocation {
- interceptors : List
- currentInterceptorIndex : int
+ proceed()
}
AnnotationAwareAspectJAutoProxyCreator --> ProxyFactory : 创建
ProxyFactory "1" --> "*" Advisor : 包含
Advisor "1" --> "1" Advice : 包含
ProxyFactory --> ReflectiveMethodInvocation : 创建
ReflectiveMethodInvocation --> Advice : 执行
二、底层运作机制详解
1. 代理创建流程
AnnotationAwareAspectJAutoProxyCreator处理流程:
java
public Object postProcessAfterInitialization(Object bean, String beanName) {
// 步骤1: 检查是否需要创建代理
if (!shouldSkip(bean.getClass(), beanName)) {
// 步骤2: 筛选匹配的Advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass());
// 步骤3: 创建代理
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, bean);
return proxy;
}
return bean;
}
protected Object createProxy(Class<?> beanClass, String beanName,
Object[] specificInterceptors, Object target) {
// 步骤4: 构建ProxyFactory
ProxyFactory proxyFactory = new ProxyFactory();
// 步骤5: 添加Advisor到ProxyFactory
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
// 步骤6: 设置代理目标
proxyFactory.setTarget(target);
// 步骤7: 创建代理对象
return proxyFactory.getProxy();
}
2. 拦截器链构建原理
ProxyFactory内部机制:
java
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Method method, @Nullable Class<?> targetClass) {
// 缓存机制提升性能
MethodCacheKey cacheKey = new MethodCacheKey(method);
if (cache.get(cacheKey) != null) { ... }
// 核心处理逻辑
List<Object> interceptorList = new ArrayList<>();
for (Advisor advisor : getAdvisors()) {
// 1. 检查是否匹配当前方法
if (advisor.getPointcut().getMethodMatcher().matches(method, targetClass)) {
// 2. 转换Advisor为MethodInterceptor
MethodInterceptor[] interceptors =
registry.getInterceptors(advisor);
// 3. 静态通知处理
if (advisor.getPointcut().isRuntime()) {
// 4. 动态通知特殊包装
interceptorList.add(new InterceptorAndDynamicMethodMatcher(
interceptors[0], advisor.getPointcut().getMethodMatcher());
} else {
// 5. 静态通知直接加入
interceptorList.add(interceptors[0]);
}
}
}
// 返回不可变列表
return interceptorList;
}
3. 拦截器链执行引擎
ReflectiveMethodInvocation核心流程:
java
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 InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
// 4. 运行时匹配判断
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
// 5. 执行动态通知逻辑
return dm.interceptor.invoke(this);
} else {
// 6. 跳过不匹配的通知
return proceed();
}
} else {
// 7. 执行静态通知
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
三、静态通知与动态通知对比
特性 | 静态通知 | 动态通知 |
---|---|---|
代理创建阶段 | 直接转换为Interceptor | 包装为InterceptorAndDynamicMethodMatcher |
匹配时机 | Bean创建时 | 每次方法调用时 |
参数依赖 | 无 | 需要方法参数 |
执行效率 | ⚡ 高(O(1)) | ⚠ 较低(每次调用需匹配) |
匹配器类型 | StaticMethodMatcher | DynamicMethodMatcher |
典型应用 | @Before无参数绑定 | @Before(args)或@annotation |
四、性能调优建议
-
避免过度使用动态通知:在频繁调用的方法上使用动态通知可能产生显著性能开销
-
缓存拦截器链:Spring采用MethodCacheKey机制缓存方法拦截器链
javapublic List<Object> getInterceptorsAndDynamicInterceptionAdvice() { // 缓存KEY:方法+目标类 MethodCacheKey cacheKey = new MethodCacheKey(method, targetClass); // 缓存处理逻辑 if (cache.containsKey(cacheKey)) { return cache.get(cacheKey); } // ... 计算逻辑 }
-
优化Pointcut表达式:
- 减少运行时检查(如避免args, this, target等)
- 优先使用execution而非annotation
-
预过滤机制:
javapublic boolean matches(Method method, Class<?> targetClass) { // 1. 快速检查(类级别) if (!isCandidateClass(targetClass)) { return false; } // 2. 方法签名匹配 return Modifier.isPublic(method.getModifiers()) && method.getName().startsWith("do"); }
五、源码级实现差异
1. 静态通知实现类
java
public class AspectJMethodBeforeAdvice implements MethodInterceptor {
public Object invoke(MethodInvocation mi) throws Throwable {
// 无匹配判断直接执行
this.adviceMethod.invoke(this.aspectInstance);
return mi.proceed();
}
}
2. 动态通知实现类
java
class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
implements MethodInterceptor, AfterAdvice {
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
} catch (Throwable ex) {
// 动态异常类型匹配
if (shouldInvokeOnThrowing(ex)) {
invokeAdviceMethod(ex);
}
throw ex;
}
}
}
六、核心流程示意图
sequenceDiagram
participant Client
participant Proxy
participant Invocation
participant AdviceA
participant AdviceB
participant Target
Client ->> Proxy: foo(100)
Proxy ->> Invocation: 创建Invocation(advices)
Invocation ->> AdviceA: proceed()
AdviceA -->> Invocation: 静态通知执行
Invocation ->> AdviceB: proceed()
rect rgba(255, 220, 0, 0.1)
AdviceB ->> AdviceB: 参数匹配(100)
AdviceB -->> Invocation: 动态通知执行
end
Invocation ->> Target: foo(100)
Target -->> Invocation: 结果
Invocation -->> Proxy: 返回
Proxy -->> Client: 结果
七、高级应用场景
1. 混合通知类型执行顺序
less
╭── @Around (before)
│ ╭── @Before (静态)
│ │ ╭── @Before (动态)
│ │ │ ╭── 目标方法
│ │ │ ╰── @AfterReturning/@AfterThrowing
│ │ ╰── @After (动态)
│ ╰── @After (静态)
╰── @Around (after)
2. 自定义Pointcut优化策略
java
public class FastDynamicPointcut extends DynamicMethodMatcherPointcut {
// 缓存匹配结果提升性能
private Map<Method, Boolean> methodCache = new ConcurrentHashMap<>();
@Override
public boolean matches(Method method, Class<?> targetClass, Object[] args) {
return methodCache.computeIfAbsent(method, m ->
computeMatch(m, targetClass, args));
}
private boolean computeMatch(Method method, Class<?> targetClass, Object[] args) {
// 复杂的匹配逻辑
}
}
结论
Spring AOP通过精妙的架构设计实现了静态通知与动态通知的高效协作:
- 编译时优化:代理创建阶段最大化处理静态信息
- 运行时延迟计算:对动态通知采用懒匹配机制
- 智能拦截器链:结合静态与动态执行路径的混合调度
- 性能平衡策略:通过缓存和预过滤减少动态匹配开销
理解这些底层机制对于构建高性能AOP应用、实现深度定制扩展至关重要。建议通过源码调试跟踪ReflectiveMethodInvocation.proceed()
方法执行路径,可直观观察拦截器链的执行状态变化。
完整代码
java
package com.dwl.dynamic_notification;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.framework.ReflectiveMethodInvocation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static com.dwl.advisor_aspect.FindEligibleAdvisorCase.getAdvisorsFromProxyCreator;
/**
* @ClassName DynamicNotification
* @Description 展示Spring如何组合静态/动态通知,及AOP代理执行的全流程
* @Version 1.0.0
* @Date 2025
* @Author By Dwl
*/
@Slf4j
public class DynamicNotificationCase {
// 切面定义 - 包含静态和动态两种通知类型
@Aspect
@Slf4j
public static class DynamicNotificationAspect {
/**
* 静态通知示例:
* 1. 无方法参数绑定
* 2. 通知实例在代理创建时确定
* 3. 执行时无需运行时匹配
*/
@Before("execution(* com.dwl.dynamic_notification.DynamicNotificationCase..foo(..))")
public void beforeA() {
log.debug("⟳ [静态通知执行] DynamicNotificationAspect.beforeA()");
}
/**
* 动态通知示例:
* 1. 需要参数绑定(args(x))
* 2. 通知实例需在每次调用时动态生成
* 3. 依赖运行时参数匹配
*/
@Before("execution(* com.dwl.dynamic_notification.DynamicNotificationCase..foo(..)) && args(x)")
public void beforeB(int x) {
log.debug("⟳ [动态通知执行] DynamicNotificationAspect.beforeB({})", x);
}
}
// 被代理的目标类
public static class DynamicNotificationBean {
public void foo(int x) {
log.info("▨ [目标方法执行] DynamicNotificationBean.foo({})", x);
}
}
// 配置类声明AOP组件
@Configuration
public static class DynamicNotificationConfig {
@Bean
public AnnotationAwareAspectJAutoProxyCreator proxyCreator() {
// 核心AOP代理创建器:负责扫描@Aspect并创建Advisor
log.debug("🚀 注册AnnotationAwareAspectJAutoProxyCreator - AOP核心代理构造器");
return new AnnotationAwareAspectJAutoProxyCreator();
}
@Bean
public DynamicNotificationAspect dynamicNotificationAspect() {
log.debug("➕ 注册切面组件: DynamicNotificationAspect");
return new DynamicNotificationAspect();
}
}
/**
* 自定义方法调用处理器:继承Spring默认实现
* 关键作用:组织通知调用链的执行顺序
*/
public static class MethodInvocation extends ReflectiveMethodInvocation {
private static final Field CURRENT_INDEX_FIELD;
private static final Field INTERCEPTORS_FIELD;
static {
try {
// 一次性初始化反射字段
CURRENT_INDEX_FIELD = ReflectiveMethodInvocation.class.getDeclaredField("currentInterceptorIndex");
CURRENT_INDEX_FIELD.setAccessible(true);
INTERCEPTORS_FIELD = ReflectiveMethodInvocation.class.getDeclaredField("interceptorsAndDynamicMethodMatchers");
INTERCEPTORS_FIELD.setAccessible(true);
} catch (NoSuchFieldException e) {
throw new RuntimeException("反射字段初始化失败", e);
}
}
public MethodInvocation(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(), args,
interceptors.size(), formatInterceptors(interceptors));
}
// 美化拦截器输出格式
private String formatInterceptors(List<Object> interceptors) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < interceptors.size(); i++) {
sb.append(String.format(" %d. %-60s → %s\n",
i + 1,
interceptors.get(i).getClass().getSimpleName(),
extractInterceptorDetail(interceptors.get(i))));
}
return sb.toString();
}
// 解析拦截器详细信息
private String extractInterceptorDetail(Object interceptor) {
try {
// 尝试解析AspectJMethodBeforeAdvice
if (interceptor.getClass().getName().contains("AspectJMethodBeforeAdvice")) {
Method getAspectMethod = interceptor.getClass().getMethod("getAspectMethod");
Method m = (Method) getAspectMethod.invoke(interceptor);
return "通知方法: " + m.getName();
}
} catch (Exception e) { /* 忽略解析错误 */ }
return interceptor.toString();
}
/**
* 增强proceed方法日志:展示调用链执行过程
*/
@Override
public Object proceed() throws Throwable {
try {
int currentIndex = (int) CURRENT_INDEX_FIELD.get(this);
@SuppressWarnings("unchecked")
List<Object> interceptors = (List<Object>) INTERCEPTORS_FIELD.get(this);
if (currentIndex < interceptors.size() - 1) {
Object currentInterceptor = interceptors.get(currentIndex + 1);
log.debug("🔹 执行拦截器 [{}/{}]: {}",
currentIndex + 1,
interceptors.size(),
currentInterceptor.getClass().getSimpleName());
} else if (currentIndex == interceptors.size() - 1) {
assert getThis() != null;
log.debug("🎯 调用目标方法: {}.{}({})",
getThis().getClass().getSimpleName(),
getMethod().getName(),
Arrays.stream(getArguments())
.map(String::valueOf)
.collect(Collectors.joining(", ")));
}
} catch (IllegalAccessException e) {
log.error("访问执行状态失败", e);
}
return super.proceed();
}
}
public static void main(String[] args) throws Throwable {
log.info("""
==========================================================================
🔍 启动动态通知深度解析流程
==========================================================================""");
// 1. 创建并初始化Spring容器
log.info("⛱ 创建Spring应用上下文");
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean(ConfigurationClassPostProcessor.class); // 配置类处理器
context.registerBean(DynamicNotificationConfig.class); // AOP配置
log.info("🔄 刷新容器 - 触发Bean初始化及AOP配置加载");
context.refresh();
// 2. 获取AOP核心组件
log.info("\n🔍 获取AnnotationAwareAspectJAutoProxyCreator实例");
AnnotationAwareAspectJAutoProxyCreator proxyCreator = context.getBean(AnnotationAwareAspectJAutoProxyCreator.class);
// 3. 获取适用当前Bean的Advisor列表
log.info("\n🕵️ 查找适用于DynamicNotificationBean的Advisor");
List<Advisor> advisorList = getAdvisorsFromProxyCreator(
proxyCreator,
DynamicNotificationBean.class,
"dynamicNotificationBean"
);
log.info("✅ 找到{}个Advisor", advisorList.size());
// 4. 手动创建代理工厂
log.info("\n🏭 构建代理工厂 (ProxyFactory)");
DynamicNotificationBean bean = new DynamicNotificationBean();
ProxyFactory factory = new ProxyFactory();
factory.setTarget(bean);
factory.addAdvisors(advisorList); // 添加切面逻辑
// 5. 生成代理对象
log.info("\n✨ 创建代理对象");
Object proxy = factory.getProxy();
log.info("代理对象类型: {}", proxy.getClass().getName());
// 6. 获取方法拦截器链
log.info("\n🔗 获取方法拦截器链");
Method fooMethod = DynamicNotificationBean.class.getMethod("foo", int.class);
List<Object> interceptionAdvices = factory.getInterceptorsAndDynamicInterceptionAdvice(
fooMethod,
DynamicNotificationBean.class
);
log.info("📌 拦截器链包含 {} 个元素", interceptionAdvices.size());
// 7. 分析拦截器链构成
log.info("\n🔬 解析拦截器链结构");
interceptionAdvices.forEach(advice -> {
try {
analyzeAdviceStructure(advice);
} catch (Exception e) {
log.error("解析拦截器失败", e);
}
});
// 8. 执行代理方法调用
log.info("\n⚡ 通过自定义调用链执行方法调用");
MethodInvocation invocation = new MethodInvocation(
proxy, // 代理对象
bean, // 目标对象
fooMethod, // 目标方法
new Object[]{100}, // 方法参数
DynamicNotificationBean.class,
interceptionAdvices // 拦截器链
);
log.info("\n🚦 开始执行拦截器链");
invocation.proceed();
log.info("\n✅ 调用链执行完成");
log.info("""
==========================================================================
🏁 动态通知解析流程结束
==========================================================================""");
}
/**
* 深度分析通知对象结构:
* 区分静态通知和动态通知(含有MethodMatcher)
*/
private static void analyzeAdviceStructure(Object advice) throws Exception {
Class<?> interceptorAndMatcherClass = Class.forName(
"org.springframework.aop.framework.InterceptorAndDynamicMethodMatcher");
if (interceptorAndMatcherClass.isInstance(advice)) {
// 动态通知解析
Field matcherField = interceptorAndMatcherClass.getDeclaredField("matcher");
matcherField.setAccessible(true);
Object matcher = matcherField.get(advice);
Field interceptorField = interceptorAndMatcherClass.getDeclaredField("interceptor");
interceptorField.setAccessible(true);
Object interceptor = interceptorField.get(advice);
log.info("""
⧉ 动态通知结构 (InterceptorAndDynamicMethodMatcher)
├─ 类型: 动态通知 (需运行时匹配)
├─ 匹配器: {}
└─ 通知器: {}""",
matcher.getClass().getName(),
interceptor);
} else {
// 静态通知解析
log.info("""
⧉ 静态通知结构
├─ 类型: 静态通知 (代理创建时确定)
└─ 通知器: {}""",
advice.getClass().getName());
}
}
}