Spring AOP源码深度解析
本文将从源码层面深入剖析Spring AOP的实现原理,包括AOP核心组件、代理创建机制、通知执行流程以及与AspectJ的集成等关键内容。
一、Spring AOP核心组件
1. AOP核心接口体系
Spring AOP基于以下核心接口构建5:
java
// 切面接口
public interface Aspect {
// 定义切面相关信息
}
// 通知接口(Advice)
public interface Advice {
// 通知是切面的具体实现逻辑
}
// 切入点接口(Pointcut)
public interface Pointcut {
ClassFilter getClassFilter();
MethodMatcher getMethodMatcher();
}
// 顾问接口(Advisor),组合了切入点和通知
public interface Advisor {
Advice getAdvice();
boolean isPerInstance();
}
// 增强器接口(IntroductionAdvisor)
public interface IntroductionAdvisor extends Advisor {
ClassFilter getClassFilter();
void validateInterfaces() throws IllegalArgumentException;
Class<?>[] getInterfaces();
}
2. 通知类型体系
Spring AOP支持五种通知类型,每种类型都有对应的接口:
java
// 前置通知
public interface MethodBeforeAdvice extends BeforeAdvice {
void before(Method method, Object[] args, @Nullable Object target) throws Throwable;
}
// 后置通知
public interface AfterReturningAdvice extends AfterAdvice {
void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable;
}
// 环绕通知
public interface MethodInterceptor extends Interceptor {
Object invoke(MethodInvocation invocation) throws Throwable;
}
// 异常通知
public interface ThrowsAdvice extends AfterAdvice {
// 无方法定义,需要自定义实现特定签名的方法
}
二、Spring AOP代理创建机制
1. AOP代理创建入口
Spring AOP代理创建的核心入口是AbstractAutoProxyCreator
类,它实现了BeanPostProcessor
接口,在Bean初始化后为符合条件的Bean创建代理对象5:
java
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 检查是否已经处理过
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 获取适用于当前Bean的通知器
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
2. 代理类型选择机制
Spring AOP通过DefaultAopProxyFactory
决定使用JDK动态代理还是CGLIB代理4:
java
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 决定使用JDK动态代理还是CGLIB代理的逻辑
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
// 如果目标类是接口或代理类本身,使用JDK动态代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 否则使用CGLIB代理
return new ObjenesisCglibAopProxy(config);
} else {
// 默认使用JDK动态代理
return new JdkDynamicAopProxy(config);
}
}
// 判断目标类是否没有实现用户提供的接口
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class<?>[] interfaces = config.getProxiedInterfaces();
return (interfaces.length == 0 || (interfaces.length == 1 && SpringProxy.class.isAssignableFrom(interfaces[0])));
}
}
3. JDK动态代理实现
JdkDynamicAopProxy
实现了InvocationHandler
接口,通过JDK的反射机制创建代理对象2:
java
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
private final AdvisedSupport advised;
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 创建JDK动态代理实例
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
// 处理Object类的方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
// 设置代理上下文(如果需要)
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 获取目标对象
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 获取适合此方法的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// 如果没有拦截器,直接调用目标方法
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// 创建方法调用
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 执行拦截器链
retVal = invocation.proceed();
}
// 处理返回值
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target && returnType != Object.class &&
returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
}
4. CGLIB代理实现
CglibAopProxy
使用CGLIB库创建代理对象,适用于目标类没有实现接口的情况3:
java
public class CglibAopProxy implements AopProxy, Serializable {
private final AdvisedSupport advised;
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
// 处理代理类
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// 验证并准备CGLIB增强器
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
// 创建回调数组
Callback[] callbacks = getCallbacks(rootClass);
enhancer.setCallbacks(callbacks);
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
// 创建并返回代理实例
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class", ex);
}
catch (Throwable ex) {
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
// 内部类MethodInterceptor实现了CGLIB的MethodInterceptor接口
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
// 类似JDK动态代理的逻辑
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 获取拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// 执行拦截器链或直接调用目标方法
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
return retVal;
}
finally {
// 清理工作
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
}
}
三、通知执行机制
1. 拦截器链的创建
Spring AOP将通知转换为拦截器链,然后按顺序执行。核心逻辑在AdvisedSupport
类中:
java
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
2. 拦截器链的执行
通知执行的核心逻辑在ReflectiveMethodInvocation
类的proceed()
方法中,它实现了责任链模式1:
java
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
protected final Object proxy;
@Nullable
protected final Object target;
protected final Method method;
protected Object[] arguments;
@Nullable
private final Class<?> targetClass;
protected final List<Object> interceptorsAndDynamicMethodMatchers;
private int currentInterceptorIndex = -1;
@Override
public Object proceed() throws Throwable {
// 执行到了最后一个拦截器,直接调用目标方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 获取下一个拦截器
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// 如果是动态方法匹配器,需要判断是否匹配
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
} else {
// 不匹配,跳过此拦截器
return proceed();
}
} else {
// 静态拦截器,直接执行
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
protected Object invokeJoinpoint() throws Throwable {
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
}
3. 各种通知类型的实现
以MethodBeforeAdviceInterceptor
为例,展示前置通知的实现:
java
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
private final MethodBeforeAdvice advice;
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// 先执行前置通知
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
// 再执行后续拦截器或目标方法
return mi.proceed();
}
}
环绕通知的实现(以AspectJAfterThrowingAdvice
为例):
java
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
// 执行后续拦截器或目标方法
return mi.proceed();
} catch (Throwable ex) {
// 如果有异常,检查是否是需要处理的异常类型
if (shouldInvokeOnThrowing(ex)) {
// 调用异常通知方法
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}
private boolean shouldInvokeOnThrowing(Throwable ex) {
return getAspectJAdviceMethod().getParameterTypes()[2].isAssignableFrom(ex.getClass());
}
}
四、Spring AOP与AspectJ集成
1. @EnableAspectJAutoProxy注解分析
@EnableAspectJAutoProxy
注解是Spring启用AspectJ风格AOP的核心5:
java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
/**
* 是否代理目标类,true使用CGLIB,false使用JDK动态代理
*/
boolean proxyTargetClass() default false;
/**
* 是否暴露代理对象到ThreadLocal
*/
boolean exposeProxy() default false;
}
2. AspectJAutoProxyRegistrar实现
java
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
// 注册AOP相关基础设施
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
// 获取@EnableAspectJAutoProxy注解的属性
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
// 设置proxyTargetClass属性
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
// 设置exposeProxy属性
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
3. AnnotationAwareAspectJAutoProxyCreator分析
AnnotationAwareAspectJAutoProxyCreator
是Spring AOP与AspectJ集成的核心类,它负责扫描@Aspect注解的类并创建代理:
java
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
@Nullable
private AspectJAdvisorFactory aspectJAdvisorFactory;
@Nullable
private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
@Override
protected List<Advisor> findCandidateAdvisors() {
// 先调用父类方法获取Spring AOP的Advisor
List<Advisor> advisors = super.findCandidateAdvisors();
// 再添加AspectJ的Advisor
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
}
4. AspectJ注解解析
BeanFactoryAspectJAdvisorsBuilder
负责扫描和解析@Aspect注解的类:
java
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 获取所有Bean的名称
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
// 遍历所有Bean,查找@Aspect注解的类
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// 获取Bean的类型
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
// 检查是否有@Aspect注解
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 解析Aspect类中的通知方法,创建Advisor
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
} else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
// 从缓存中获取Advisor
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
} else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
if (factory != null) {
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
return advisors;
}
五、Spring AOP与AspectJ的区别
特性 | Spring AOP | AspectJ |
---|---|---|
实现方式 | 基于动态代理(JDK/CGLIB) | 编译时织入(CTW)、后编译织入或加载时织入(LTW) |
支持的连接点 | 仅限方法执行 | 全面(方法、构造器、字段、异常处理点等) |
性能 | 运行时开销较大 | 编译时处理,运行时无额外开销 |
功能范围 | 仅支持方法级别的切面 | 支持字段、构造器、方法等更细粒度切面 |
织入时机 | 运行时织入 | 编译时/加载时织入 |
学习曲线 | 较简单 | 较复杂 |
依赖 | 仅需Spring框架 | 需要AspectJ编译器或织入器 |
适用场景 | 适合大多数Spring应用 | 需要更强大切面功能或更高性能要求的场景 |
六、Spring AOP工作流程总结
Spring AOP的完整工作流程可以概括为以下几个主要步骤:
- AOP配置解析:解析@AspectJ注解或XML配置,识别切面、通知和切入点
- 注册自动代理创建器:通过@EnableAspectJAutoProxy注册AnnotationAwareAspectJAutoProxyCreator
- 扫描切面类:扫描并解析带有@Aspect注解的类,将通知方法转换为Advisor
- 创建代理对象:在Bean初始化后,AbstractAutoProxyCreator为符合条件的Bean创建代理
- 选择代理类型:根据目标类是否实现接口,选择JDK动态代理或CGLIB代理
- 执行增强逻辑:当调用代理对象的方法时,按照责任链模式执行各种通知
总结
Spring AOP是Spring框架的核心特性之一,它通过动态代理机制在运行时为目标对象创建代理,并在代理中织入增强逻辑。深入理解Spring AOP的源码实现,不仅有助于我们更好地使用AOP功能,也能让我们学习到优秀的设计模式和编程思想。
Spring AOP的设计非常灵活,它通过责任链模式处理各种通知,通过工厂模式创建代理对象,并与IoC容器紧密集成,为Java应用提供了强大的面向切面编程支持。