我们之前分析了Spring bean创建的核心源码以及Spring相关注解的源码,这一节开始我们就要开始分析Spring AOP的源码,那这个Spring AOP的源码入口在哪里呢?还记得我们分析创建bean核心流程,在创建bean的时候Spring提供了各种bean的后置处理器,我们猜测AOP代理对象可能是通过这些后置处理来创建的,我们现在先看下bean实例化之前Spring为我们提供的后置处理器。我们看下如下代码:
我们可以看到在bean创建之前,提供了一个机会创建生成代理对象,所以我们猜测这个Spring AOP的代理对象,应该是在这个resolveBeforeInstantiation方法中进行创建的。我们到这个resolveBeforeInstantiation方法中看下:
我们发现resolveBeforeInstantiation()方法会先看一下这个bean在实例化之前是够解析过,那么第一次进来的话这个mbd.beforeInstantiationResolved变量为null,所以整个条件为true。接着会判断是否存在实现了InstantiationAwareBeanPostProcessor接口的beanPostProcessor,如果满足这个条件的话,代码会继续往下走,接着就会调用applyBeanPostProcessorsBeforeInstantiation()方法。
我们到方法applyBeanPostProcessorsBeforeInstantiation中看下:
可以看到,这里其实就是调用了一个getBeanPostProcessors()方法获取到了所有的BeanPostProcessor,然后循环调用了BeanPostProcessor的postProcessBeforeInstantiation()方法,也就是实例化前的处理。那到底执行的是哪一个处理器呢?我们看下InstantiationAwareBeanPostProcessor 的子类有哪些?
可以看到 InstantiationAwareBeanPostProcessor 的子类有很多,但是我们找到了一个和AOP有关的类 AnnotationAwareAspectJAutoProxyCreator,这个就是针对AspectJ注解的自动代理创建器。我们到这个类中看下postProcessBeforeInstantiation方法到底做了什么?
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
@Nullable
private List includePatterns;
@Nullable
private AspectJAdvisorFactory aspectJAdvisorFactory;
@Nullable
private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;
public void setIncludePatterns(List patterns) {
this.includePatterns = new ArrayList<>(patterns.size());
for (String patternText : patterns) {
this.includePatterns.add(Pattern.compile(patternText));
}
}
public void setAspectJAdvisorFactory(AspectJAdvisorFactory aspectJAdvisorFactory) {
Assert.notNull(aspectJAdvisorFactory, "AspectJAdvisorFactory must not be null");
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
}
@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 findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
List advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
@Override
protected boolean isInfrastructureClass(Class> beanClass) {
// Previously we setProxyTargetClass(true) in the constructor, but that has too
// broad an impact. Instead we now override isInfrastructureClass to avoid proxying
// aspects. I'm not entirely happy with that as there is no good reason not
// to advise aspects, except that it causes advice invocation to go through a
// proxy, and if the aspect implements e.g the Ordered interface it will be
// proxied by that interface and fail at runtime as the advice method is not
// defined on the interface. We could potentially relax the restriction about
// not advising aspects in the future.
return (super.isInfrastructureClass(beanClass) ||
(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
}
protected boolean isEligibleAspectBean(String beanName) {
if (this.includePatterns == null) {
return true;
}
else {
for (Pattern pattern : this.includePatterns) {
if (pattern.matcher(beanName).matches()) {
return true;
}
}
return false;
}
}
private class BeanFactoryAspectJAdvisorsBuilderAdapter extends BeanFactoryAspectJAdvisorsBuilder {
public BeanFactoryAspectJAdvisorsBuilderAdapter(
ListableBeanFactory beanFactory, AspectJAdvisorFactory advisorFactory) {
super(beanFactory, advisorFactory);
}
@Override
protected boolean isEligibleBean(String beanName) {
return AnnotationAwareAspectJAutoProxyCreator.this.isEligibleAspectBean(beanName);
}
}
}
但是我们在这个类中并没有找到postProcessBeforeInstantiation方法,而AnnotationAwareAspectJAutoProxyCreator 又继承了AspectJAwareAdvisorAutoProxyCreator 对象,所以我们到它的父类AspectJAwareAdvisorAutoProxyCreator 中找一下
我们在这个AspectJAwareAdvisorAutoProxyCreator 中也没有找到该方法,我发现AspectJAwareAdvisorAutoProxyCreator 继续了AbstractAutoProxyCreator类,所以我们继续在AbstractAutoProxyCreator这个类中找一下:
可以看到,我们AbstractAutoProxyCreator类中找到了该方法。
我们在看一下AnnotationAwareAspectJAutoProxyCreator 类的继承关系:
可以发现AnnotationAwareAspectJAutoProxyCreator的父类是AspectJAwareAdvisorAutoProxyCreator,而AspectJAwareAdvisorAutoProxyCreator的父类是AbstractAdvisorAutoProxyCreator,然后AbstractAdvisorAutoProxyCreator的父类才是这个AbstractAutoProxyCreator类。而AnnotationAwareAspectJAutoProxyCreator正是从这个AbstractAutoProxyCreator继承过来了postProcessBeforeInstantiation()方法,也就是说真正的处理逻辑,其实是在AbstractAutoProxyCreator的postProcessBeforeInstantiation()方法中。我们就来看下这个AbstractAutoProxyCreator类的postProcessBeforeInstantiation()方法吧:
看到了非常关键的一行代码TargetSource targetSource = getCustomTargetSource(beanClass, beanName),这行代码上边注释的意思大概是“如果我们指定了targetSource,那么就在这里创建一个代理”,这里我们得到了一个非常关键的信息,那就是只有指定了targetSource才会在这里创建代理。我们一般是不会指定targetSource的,也就是一般是不会在这里创建代理的。由于我们没有指定targetSource,所以getCustomTargetSource(beanClass, beanName)方法得到的targetSource为null,最终这个postProcessBeforeInstantiation()方法返回的是个null,我们现在继续往下看代码:
一般这些beanPostProcessor的postProcessBeforeInstantiation()方法都会返回null。此时发现这个bean为null,那么这个bean != null的条件就不满足,所以这行代码bean = applyBeanPostProcessorsAfterInitialization(bean, beanName)是不会执行的,说白了就是只在特定条件下才会执行,这个特定条件就是我们指定了targetSource的情况。那这个时候resolveBeforeInstantiation()方法就执行完毕了,由于我们没有指定targetSource,所以此时bean为null,因此resolveBeforeInstantiation()方法返回的也是null,如下图:
也就是说此时Object bean = resolveBeforeInstantiation(beanName, mbdToUse)这行代码执行完之后,这个bean为null,那么bean != null的条件就不满足,此时就不会直接返回bean,那这个时候代码就会继续往下运行,那接下来就开始执行Object beanInstance = doCreateBean(beanName, mbdToUse, args)这行代码了,也就是开始正常的进行bean的实例化和初始化过程。这个resolveBeforeInstantiation()方法的意义到底是什么?其实它的意思就是说,如果我们指定了targetSource,那么可以在这里创建一个代理直接返回,就不需要走下边的实例化和初始化阶段了,因为指定了targetSource后,这个bean就由开发人员自己负责完成创建了。而如果没有指定targetSource,那么就按照正常流程往下执行bean的实例化和初始化,说白了就是注释上说的:“给你一个返回代理的机会”。不过一般我们都不会指定targetSource,所以代码会继续往下运行,此时就会来运行doCreateBean()这个方法来创建bean了,那AOP真正的自动代理时机会不会在这个doCreateBean()方法中呢?
我们接着到doCreateBean方法中看下:
我们可以看到在doCreateBean()方法中有这么关键的几步:
1、首先调用createBeanInstance(beanName, mbd, args)创建了一个bean实例。
2、调用applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)找到了被@Autowired等注解标注的字段和方法, 为下一步的注入做准备。
3、接着调用populateBean(beanName, mbd, instanceWrapper)为bean填充属性。
4、最后调用initializeBean(beanName, exposedObject, mbd)完成bean的初始化。
首先createBeanInstance()被排除,因为根据我们IOC部分的知识知道,这个createBeanInstance()主要就是创建一个bean实例出来,它里边是没有AOP相关的逻辑的。接着是applyMergedBeanDefinitionPostProcessors()和populateBean(),它们都是和属性注入相关的东西,所以这个里面也没有AOP相关的逻辑。所以只剩下了initializeBean(),我们到这个initializeBean 方法中看下:
我们看到了极为关键的两种beanPostProcessor,一个是初始化前处理的beanPostProcessor,另外一个是初始化后处理的beanPostProcessor,我们要找的AOP逻辑极有可能就在这两个beanPostProcessor的其中一个里边。我们就先来看下applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)里边是怎么玩儿的吧,点进去这个方法后,代码如下:
这里的核心逻辑就是遍历所有的BeanPostProcessor,然后分别调用它们的postProcessBeforeInitialization()方法。在这个方法中也会调用AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInitialization()方法。我们到这个AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInitialization方法中看下:
我们同样在AbstractAutoProxyCreator这个类中找到了该方法,但是这个里面什么也没有做。说白了这里根本没有对bean做任何处理,就相当于一个“空实现”,也就是说AOP的逻辑不在初始化前处理中。我们在回到之前的代码:
我们接着来看下这个applyBeanPostProcessorsAfterInitialization()方法,我们看这里:
在这个方法中同样也会调用AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization()方法。我们还是到AbstractAutoProxyCreator这个类中找这个postProcessAfterInitialization方法:
我们发现一行极为关键的代码return wrapIfNecessary(bean, beanName, cacheKey),从名字上来看,这个wrapIfNecessary()方法会对bean进行包装,包装完毕后,直接将包装好的bean给返回了。那wrapIfNecessary()方法在进行包装的时候,会不会就是将普通的bean给包装成了AOP代理呢?那我们现在就点进去wrapIfNecessary()方法看下:
1、首先是Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null),通过这个方法的名字,我们知道,它主要是用来获取当前bean对应的增强。
2、将获取的增强specificInterceptors交给了createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)),而这个createProxy()方法会根据这些增强生成代理对象proxy,最后将这个代理对象proxy返回,这样就将一个普通的bean替换为了AOP代理。
3、如果这个bean没有相应的增强,即specificInterceptors = null时,是不会给这个bean创建AOP代理的。
梳理一下AOP的执行时机:
需要注意的一点就是,当我们指定了targetSource的时候,除了会调用实例化前处理applyBeanPostProcessorsBeforeInstantiation()外,还会调用初始化后处理applyBeanPostProcessorsAfterInitialization(),对应的代码如下:
由于targetSource一般都不会指定,从而导致bean != null不会满足,所以直接跳过了红框中的这行代码。我们发现resolveBeforeInstantiation()和initializeBean()竟然调了相同的方法,那就是applyBeanPostProcessorsAfterInitialization(),而整个创建AOP代理的关键代码就在这个applyBeanPostProcessorsAfterInitialization()中。所以我们现在明白了,不管我们是否指定了targetSource,都会依赖初始化后处理applyBeanPostProcessorsAfterInitialization()来完成AOP代理的创建。
我们通过流程图梳理今天的内容:



