Spring AOP 源码阅读
Spring AOP 大致流程
Spring 代理对象创建流程
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
...
}
引入了 AspectJAutoProxyRegistrar.class
在AspectJAutoProxyRegistrar中, 通过在初始化容器实例化对象之前, 回调registerBeanDefinitions()
的方法,向BeanDefinition中注册一个 AnnotationAwareAspectJAutoProxyCreator.class
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
...
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
...
}
在上图中我们看到AnnotationAwareAspectJAutoProxyCreator
是实现了BeanPostProcessor接口的,
而实现BeanPostProcessor后,当Spring在Bean的初始化后会调用其postProcessAfterInitialization()
方法,AOP逻辑由此开始
接着进入postProcessAfterInitialization()
这个方法的逻辑
找到了AnnotationAwareAspectJAutoProxyCreator
的父类AbstractAutoProxyCreator
中的这个方法 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
@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;
}
继续进入方法中wrapIfNecessary()
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 判断当前bean是否存在匹配的advice, 如果存在则要生成一个代理对象
// 此处根据类以及类中的方法去匹配到Interceptor(也就是advice). 然后生成代理对象,
// 代理对象在执行的时候, 还会根据当前执行的方法去匹配
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
// advisedBeans记录了某个Bean已经进行过AOP了
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;
}
继续进入createProxy()
方法
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// advisedBeans表示已经判断过来的的bean, false表示此bean不需要进行Aop
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 当前正在创建Bean不用进行AOP, 比如切面Bean
// shouldSkip() 是模板方法, 子类可以去扩展的
// org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.isInfrastructureClass
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
// 直接返回
return bean;
}
// ☆ ->
// 判断当前bean是否存在匹配的advice, 如果存在则要生成一个代理对象
// 此处根据类以及类中的方法去匹配到Interceptor(也就是advice). 然后生成代理对象,
// 代理对象在执行的时候, 还会根据当前执行的方法去匹配
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
// advisedBeans记录了某个Bean已经进行过AOP了
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;
}
该方法做了如下事情:
- 进入方法后判断当前Bean是需要进行AOP,advisedBeans相当于是一个缓存,在下面判断过的bean会放入这个map中,避免再次到下面去判断。
- 判断当前bean是否存在匹配的advice, 匹配的条件是向根据类名,再根据方法名(如果有必要的话),如果存在则要生成一个代理对象,此处根据类以及类中的方法去匹配到Interceptor(也就是advice). 然后生成代理对象,
- 通过 AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors()这个方法找到所有的Advisor
@Override
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
// 找到所有Advisor类型的Bean对象
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
// 再从所有的切面中解析得到Advisor对象
if (this.aspectJAdvisorsBuilder != null) {
// 解析AspectJ中定义的切面方法, 并加到advisors中
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
在该方法中会调用BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors()
把Bean都解析成Advisor, 并在list中返回
buildAspectJAdvisors()
代码如下:
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<>();
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
Class<?> beanType = this.beanFactory.getType(beanName, false);
if (beanType == null) {
continue;
}
// 判断类上是否有AspectJ注解
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
// 切面的注解信息
AspectMetadata amd = new AspectMetadata(beanType, beanName);
// 如果@Aspect不是perthis、pertarget, 那么一个切面只会生成一个对象(单例),
// 并且会将该切面中的所对应的Advisor对象进行缓存
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// ☆ ->
// 利用BeanFactoryAspectInstanceFactory来解析Aspect类
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
// 缓存切面所对应的所有Advisor对象
this.advisorsCache.put(beanName, classAdvisors);
} else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
} else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
// 利用PrototypeAspectInstanceFactory来解析Aspect类
// PrototypeAspectInstanceFactory的父类为BeanFactoryAspectInstanceFactory
// 这两个Factory的区别在于PrototypeAspectInstanceFactory的构造方法中会判断切面Bean是不是原型,
// 除此之外没有其他区别
//
// 所以主要就是BeanFactoryAspectInstanceFactory来负责生成切面实例对象
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
// 如果切面已经找到过了,那么则遍历每个切面是否缓存了对应的Advisor,如果没有缓存则进行解析得到Advisor
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);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
上面方法中: List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
......
// 获取切面类中[没有]加@Pointcut的方法,进行遍历生成Advisor, 并排序
for (Method method : getAdvisorMethods(aspectClass)) {
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
// 如果是pertarget或perthis,则会多生成一个Advisor并放在最前面
// 在一个代理对象调用方法的时候,就会执行该Advisor,并且会利用lazySingletonAspectInstanceFactory来生成一个切面Bean
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// 找到哪些字段上加了@DeclareParents注解,把这些字段以及对于的注解解析封装为Advisor,生成代理对象时会把对于的接口添加到ProxyFactory中
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
在上面的代码中: getAdvisorMethods(aspectClass)
会获取切面类中没有加@Pointcut的方法,进行遍历生成Advisor, 并排序。
排序规则:
static {
// 先更具下面的注解排序
Comparator<Method> adviceKindComparator = new ConvertingComparator<>(
new InstanceComparator<>(
Around.class,
Before.class,
After.class,
AfterReturning.class,
AfterThrowing.class
),
(Converter<Method, Annotation>) method -> {
AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
return (ann != null ? ann.getAnnotation() : null);
});
// 再根据方法名排序
Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
adviceMethodComparator = adviceKindComparator.thenComparing(methodNameComparator);
}
继续回到 Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
该方法返回的对象是Advisor的实现类InstantiationModelAwarePointcutAdvisorImpl
。
在InstantiationModelAwarePointcutAdvisorImpl#instantiateAdvice()
方法中会根据方法上的注解生成对应的Advice。
// 按不同的注解类型得到不同的Advice
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException("Unsupported advice type on method: " + candidateAdviceMethod);
}
各注解对应的MethodInterceptor
- @Before对应的是AspectJMethodBeforeAdvice,在进行动态代理时会把AspectJMethodBeforeAdvice转成MethodBeforeAdviceInterceptor
- 先执行advice对应的方法
- 再执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法
- @After对应的是AspectJAfterAdvice,直接实现了MethodInterceptor
- 先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法
- 再执行advice对应的方法
- @Around对应的是AspectJAroundAdvice,直接实现了MethodInterceptor
- 直接执行advice对应的方法,由@Around自己决定要不要继续往后面调用
- @AfterThrowing对应的是AspectJAfterThrowingAdvice,直接实现了MethodInterceptor
- 先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法
- 如果上面抛了Throwable,那么则会执行advice对应的方法
- @AfterReturning对应的是AspectJAfterReturningAdvice,在进行动态代理时会把AspectJAfterReturningAdvice转成AfterReturningAdviceInterceptor
- 先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法
- 执行上面的方法后得到最终的方法的返回值
- 再执行Advice对应的方法
在AspectJ中有五种, 而Spring中只有四种
继续回到 createProxy()
方法的 proxyFactory.getProxy(classLoader);
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
// 拿到被代理的类
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
// 如果被代理的类的本身就已经是在Cglib所生成的代理类了
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
// 获取真正的被代理类
proxySuperClass = rootClass.getSuperclass();
// 获取被代理类所实现的接口
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
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 ClassLoaderAwareGeneratorStrategy(classLoader));
// 获取和被代理类所匹配的Advisor
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
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) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}