Spring AOP原理
Spring AOP通过运行时动态代理实现横切关注点的分离。
核心概念
| 概念 | 说明 | 示例 |
|---|---|---|
| Joinpoint | 连接点,程序执行的特定点 | 方法调用、异常抛出 |
| Pointcut | 切点,匹配连接点的表达式 | execution(* com.example..(..)) |
| Advice | 通知,在切点执行的代码 | @Before、@After、@Around |
| Aspect | 切面,通知+切点的组合 | @Aspect标注的类 |
| Weaving | 织入,将切面应用到目标对象 | 运行时动态代理 |
| Target | 目标对象,被代理的对象 | 业务Bean |
代理对象创建流程
Java
┌─────────────────────────────────────────────────────┐
│ Spring容器启动 │
└─────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ AbstractAutoProxyCreator.postProcessAfterInitialization │
│ (BeanPostProcessor的后置处理) │
└─────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 查找匹配当前Bean的所有Advisor (切面增强器) │
└─────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 存在匹配的Advisor → 创建代理对象 │
│ 不存在 → 返回原始Bean │
└─────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 选择代理方式:JDK动态代理 或 CGLIB │
└─────────────────────────────────────────────────────┘
核心类解析
AnnotationAwareAspectJAutoProxyCreator
Java
// AOP核心处理器,实现BeanPostProcessor
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
// Bean初始化后创建代理
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.advisedBeans.containsKey(cacheKey)) {
return bean; // 已处理过
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 查找匹配的Advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(
bean.getClass(), beanName, specificTargetSource);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
Object proxy = createProxy(bean.getClass(), beanName,
specificInterceptors, specificTargetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return bean;
}
}
代理对象创建
Java
protected Object createProxy(Class<?> beanClass, String beanName,
Object[] specificInterceptors, TargetSource targetSource) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// 决定使用哪种代理方式
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 构建Advisor链
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
return proxyFactory.getProxy(getProxyClassLoader());
}
切点表达式解析
Java
// AspectJExpressionPointcut解析切点表达式
public class AspectJExpressionPointcut extends AbstractExpressionPointcut
implements ClassFilter, MethodMatcher {
private PointcutParser pointcutParser;
private PointcutExpression pointcutExpression;
// 类匹配
@Override
public boolean matches(Class<?> targetClass) {
return pointcutExpression.couldMatchJoinPointsInType(targetClass);
}
// 方法匹配
@Override
public boolean matches(Method method, Class<?> targetClass) {
ShadowMatch shadowMatch = pointcutExpression.matchesMethodExecution(method);
return shadowMatch.alwaysMatches();
}
}
通知执行链
Java
// ReflectiveMethodInvocation - 通知链式调用
public class ReflectiveMethodInvocation implements ProxyMethodInvocation {
protected Object invokeJoinpoint() throws Throwable {
// 执行目标方法
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint(); // 执行目标方法
}
// 获取下一个拦截器并执行
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
通知适配器
text
// 将不同类型通知适配为MethodInterceptor
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry {
private final List<AdvisorAdapter> adapters = new ArrayList<>(3);
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
}
// @Before适配器示例
class MethodBeforeAdviceAdapter implements AdvisorAdapter {
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}
}
要点总结
- Spring AOP基于BeanPostProcessor在Bean初始化后创建代理
- 代理方式由proxyTargetClass和接口情况共同决定
- Pointcut表达式由AspectJ解析器处理
- 通知通过责任链模式顺序执行
- 五种通知最终都被适配为MethodInterceptor
📝 发现内容有误?点击此处直接编辑