上一篇文章Spring中AOP源码浅析①讲到AOP中实际是通过BeanPostProcesser后置处理器实现的。后置处理器就是在Bean初始化前后进行拦截调用。
那么我们的后置处理器是如何加载和初始化呢?(后置处理器是一类特殊的Bean)
猜想一下,肯定是在普通单例Bean之前进行加载和初始化操作,只有先加载了处理器才能通过处理器去拦截Bean。
那么我们就从业务Bean的加载这一步看源码是如何实现的,实际业务Bean和处理器Bean加载过程类似。还是使用Spring中AOP的使用这篇文章的代码运行调试。(测试类、配置类MainConfig、业务类Fun、切面类LogAspect并且加上相应注解)
第一步Spring容器通过配置类创建Ioc容器:
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(MainConfig.class);
配置类在这篇文章有提到聊一聊SpringBean的生命周期——创建、初始化、销毁。
点进去AnnotationConfigApplicationContext 这个类查看
public AnnotationConfigApplicationContext(Class>... annotatedClasses) {
this();
//注册配置类
register(annotatedClasses);
//刷新Spring容器上下文
refresh();
}
处理器和Bean的加载初始化过程就在这个refresh()方法里,点进去
...
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
...
// Register bean processors that intercept bean creation.
//注册拦截Bean创建的后置处理器
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//实例化所有剩余非懒加载单例Bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
...
从源码看拦截的后置处理器的加载是比非懒加载单例Bean要早的。分别是registerBeanPostProcessors(beanFactory),finishBeanFactoryInitialization(beanFactory)这两个方法。
跟进registerBeanPostProcessors(beanFactory)继续看,发现是调用了PostProcessorRegistrationDelegate委托类的registerBeanPostProcessors()方法。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
....
//区分操作,分离出实现PriorityOrdered接口、Ordered接口和剩余的后置处理器并放入List
List priorityOrderedPostProcessors = new ArrayList<>();
List internalPostProcessors = new ArrayList<>();
List orderedPostProcessorNames = new ArrayList<>();
List nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
....
//1、首先注册实现PriorityOrdered接口的后置处理器
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
//2、接下来注册实现Ordered接口的后置处理器
List orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
//3、现在注册所有普通的后置处理器
List nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
//4、最后 重新注册所有内部后置处理器
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
....
}
现在看来后置处理器的加载顺序也很清楚了:
在这里介绍一下这两个优先级的接口,PriorityOrdered继承自Ordered,两个接口都通过getOrder()判断优先级。
我们在分离出List这一步之后打个断点,看一下四个List容器里面分别放了哪几个后置处理器。
发现涉及AOP的处理器(org.springframework.aop.config.internalAutoProxyCreator)在 orderedPostProcessorNames 这里,这说明这个后置处理器是需要优先加载的。在以上分析的第二步注册。
在refresh()中的注册拦截Bean创建的后置处理器registerBeanPostProcessors(beanFactory)方法执行完毕后,我们再来看下实例化所有剩余非懒加载单例Bean方法finishBeanFactoryInitialization(beanFactory)的执行过程。
执行了beanFactory.preInstantiateSingletons() 点进去看,执行到这一步发现会遍历所有的BeanName(包含了处理器和业务Bean),之后调用了getBean(beanName),里面调用doGetBean(name, null, null, false)。这里发现我们的普通业务Bean和后置处理器都会进入到doGetBean()方法,这说明Bean的实例化的过程是一致的。
那么我们就直接看增强代码是如何加入到业务Bean的。在doGetBean()这一步仔细看一下代码,找到创建单例Bean的步骤,也可以加断点debug。
protected T doGetBean(final String name, @Nullable final Class requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// 检查缓存中是否存在
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
...
这一步会先拿缓存,若没有才会实例化。缓存和我们的工厂一样,实际都是一个Map对象。
/** Cache of singleton objects: bean name --> bean instance */
private final Map singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map> singletonFactories = new HashMap<>(16);
/** Cache of early singleton objects: bean name --> bean instance */
private final Map earlySingletonObjects = new HashMap<>(16);
在doGetBean()这一步查看,
...
// Create bean instance.
// 创建Bean实例
if (mbd.isSingleton()) { //Bean的定义为单例
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
......
看代码推测这一步是创建单例Bean实例的步骤,可以在这打个断点debug,进入createBean(beanName, mbd, args);方法。
现在只关注我们的业务Bean,其他处理器则可以跳过。
createBean这里面前面都是一些解析判断准备工作。debug执行到了这里,给后置处理器一个机会去返回代理对象而不是目标Bean实例。推测这里会有后置处理器 执行相关的代码。
...
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//给后置处理器一个返回代理对象的机会而不是目标Bean实例
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
...
但是执行完毕之后 bean=null ,并没有出现预想的结果。
注释翻译:给后置处理器一个返回代理对象的机会而不是目标Bean实例
该方法翻译:实例化前解析
再次运行,进入到方法体内部。
/**
* Apply before-instantiation post-processors, resolving whether there is a
* before-instantiation shortcut for the specified bean.
* 请求实例化之前的后置处理器,以解析指定的bean是否存在实例化之前的快捷方式。
*/
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.确保此时已经解析了该类
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
这里出现了InstantiationAwareBeanPostProcessors后置处理器,那么就和我们之前提到的AnnotationAwareAspectJAutoProxyCreator(Bean名称:internalAutoProxyCreator )对应到了,因为后者实际就是前者的实现。设想AOP相关的这个后置处理器应该会在这里执行。进入 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);。
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class> beanClass, String beanName) {
//遍历所有后置处理器
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//得到InstantiationAwareBeanPostProcessor相关的这个后置处理器
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//执行前置方法
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
发现确实在这里执行了相应的前置处理方法。这里应该是由InstantiationAwareBeanPostProcessor相关的这个后置处理器去执行前置方(internalAutoProxyCreator)。
resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd)
继续向下执行,进入到这个方法。(因为这句代码执行完毕后有日志打印:完成创建Bean实例)
....
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
....
进去之后发现是要封装一个BeanWrapper对象。
...
// Initialize the bean instance.
Object exposedObject = bean;
try {
//属性赋值
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
...
这一句执行完之后在debugger窗口发现exposedObject 变成了一个代理对象
之后继续往后执行就返回了。所以肯定是initializeBean(beanName, exposedObject, mbd);这一步执行了相应的方法创建的业务Bean。
点击源代码进去:
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
这里就很清楚了,主要做了四件事:
所以代理的创建过程一定是在后置处理器的执行过程中,刚才调试过程中初始化后置操作执行完之后才返回的业务代理对象。所以一定是某个后置处理器(BeanPostProcessor)的后置方法执行完之后才创建的代理对象。
在上篇文章Spring中AOP源码浅析①讲到AnnotationAwareAspectJAutoProxyCreator实际是一个后置处理器(SmartInstantiationAwareBeanPostProcessor 继承InstantiationAwareBeanPostProcessor),所以我们只要看后置处理器的执行代码就知道具体的Bean生成过程。
不管我们的Bean如何改变都脱离不了以上的过程。画个图总结一下
AnnotationAwareAspectJAutoProxyCreator 这个AOP处理器具体的前置、后置创建代理的过程下一篇文章再聊。