Spring源码阅读----Spring IoC之registe
概述
在invokeBeanFactoryPostProcessors方法执行之后,紧接着执行的是registerBeanPostProcessors,该方法是注册所有的 BeanPostProcessor,将所有实现了 BeanPostProcessor 接口的类加载到 BeanFactory 中。
BeanPostProcessor名字上跟BeanFactoryPostProcessor有点类似,那它们的功能是否也相似呢?对,它也是后置处理器,属于扩展点。
BeanPostProcessor 接口是 Spring 初始化 bean 时对外暴露的扩展点,Spring IoC 容器允许 BeanPostProcessor 在容器初始化 bean 的前后,添加自己的逻辑处理。在这边只是注册到 BeanFactory 中,具体调用是在 bean 初始化的时候。
在所有 bean 实例化时,执行初始化方法前会调用所有 BeanPostProcessor 的 postProcessBeforeInitialization 方法,执行初始化方法后会调用所有 BeanPostProcessor 的 postProcessAfterInitialization 方法。(通俗点来讲就是:比如Spring容器加载了bean之后,如果需要对所有的bean,或者某部分bean进行功能增强时,此时就可以采用一个叫做后置处理器的工具来对bean进行增强或扩展,Spring中的后置处理器也就是BeanPostProcessor接口)。
所以我们可以知道,BeanFactoryPostProcessor 是针对 BeanFactory 的扩展,主要用在 bean 实例化之前,读取 bean 的定义,并可以修改它;BeanPostProcessor 是针对 bean 的扩展,主要用在 bean 实例化之后,执行初始化方法前后,允许开发者对 bean 实例进行修改。
BeanPostProcessor 接口
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
registerBeanPostProcessors解析
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//委托给PostProcessorRegistrationDelegate来执行registerBeanPostProcessors
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
【源码解析】,PostProcessorRegistrationDelegate.registerBeanPostProcessors
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 注释1. 从beanFactory获取所有实现BeanPostProcessor接口的类
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
//注释2. 新建一个BeanPostProcessorChecker(主要用于记录信息)对象,并添加到beanFactory中
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 注释3. 定义不同的列表集合用于区分:
// 注释3-1. 实现PriorityOrdered接口的BeanPostProcessor、实现Ordered接口的BeanPostProcessor、普通BeanPostProcessor以及Spring内部的BeanPostProcessor---internalPostProcessors:类型是 MergedBeanDefinitionPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
//注释3-2. 遍历postProcessorNames, 将BeanPostProcessors按上面四种不同的列表区分开
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
//注释3-3. 如果ppName对应的Bean实例,也实现了MergedBeanDefinitionPostProcessor接口
//则将ppName对应的Bean实例添加到internalPostProcessors
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
// 注释4. 首先,注册实现了 PriorityOrdered 接口的 BeanPostProcessors
//注释4-1. 对priorityOrderedPostProcessors进行排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//注释4-2. 对priorityOrderedPostProcessors进行注册
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
//注释5. 下一步,注册实现了 Ordered 接口的 BeanPostProcessors
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
//注释5-1. 获取 ppName对应的BeanPostProcessor实例对象
//并添加到orderedPostProcessors中,准备注册
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
//注释5-2.如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口
//则将该实例添加到internalPostProcessors
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//注释5-3. 排序、注册
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
// 注释6. 现在,注册常规 BeanPostProcessors
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 注册
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
// 注释7. 最后, 重新注册所有内部BeanPostProcessors(相当于内部的BeanPostProcessor会被移到处理器链的末尾)
// 这里看起来是重复注册了,但是每次注册调用的底层方法都会先移除已存在的 beanPostProcessor,然后再加进去,最后还是保存唯一
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
// 注释9.创建一个ApplicationListenerDetector对象并且注册到容器,这就是前面计算beanProcessorTargetCount的值时加一的原因
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
如上,具体步骤在注释处标明。详细来解析一下部分内容
注释4-1. 对priorityOrderedPostProcessors进行排序,类似前文的排序。
注释4-2. 对priorityOrderedPostProcessors进行注册(见源码解析1)
【源码解析1】 registerBeanPostProcessors
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
// 对每个bean都调用beanFactory的addBeanPostProcessor方法来注册
beanFactory.addBeanPostProcessor(postProcessor);
}
}
BeanFactory的addBeanPostProcessor方法,在AbstractBeanFactory类中实现:
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
//如果beanPostProcessor已经存在则移除(可以起到排序的效果,beanPostProcessor可能本来在前面,移除再添加,则变到最后面)
this.beanPostProcessors.remove(beanPostProcessor);
// Track whether it is instantiation/destruction aware
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
//如果beanPostProcessor是InstantiationAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true
//该变量用于指示beanFactory是否已注册过InstantiationAwareBeanPostProcessors
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
//如果beanPostProcessor是DestructionAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true
//该变量用于指示beanFactory是否已注册过DestructionAwareBeanPostProcessor
this.hasDestructionAwareBeanPostProcessors = true;
}
// Add to end of list
//将beanPostProcessor添加到beanPostProcessors缓存
this.beanPostProcessors.add(beanPostProcessor);
}
所以这里可以看出该方法作用就是将入参的 BeanPostProcessor 添加到BeanFactory中的beanPostProcessors列表中,如果存在则删除,把它添加到末尾。这里也解释了注释7里面的疑问,不会重复注册。
hasInstantiationAwareBeanPostProcessors 和 hasDestructionAwareBeanPostProcessors 变量用于指示 beanFactory 是否已注册过 InstantiationAwareBeanPostProcessors 和 DestructionAwareBeanPostProcessor,这里暂时用不上,不过在之后的 IoC 创建过程会用到这两个变量。
BeanPostProcessor的实现类如何被使用
运行顺序如下:
- Spring IOC容器实例化Bean
- 调用BeanPostProcessor的postProcessBeforeInitialization方法
- 调用bean实例的初始化方法
- 调用BeanPostProcessor的postProcessAfterInitialization方法
通过测试来验证一下
- 创建一个TestBeanPostProcessor类,实现BeanPostProcessor接口
package com.zhlab.ssm.demo.web;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.PriorityOrdered;
import org.springframework.stereotype.Component;
/**
* @ClassName TestBeanPostProcessor
* @Description //TestBeanPostProcessor
* @Author singleZhang
* @Email 405780096@qq.com
* @Date 2021/1/22 0022 下午 5:16
**/
@Component
public class TestBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("TestBeanPostProcessor#postProcessBeforeInitialization");
System.out.println(beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("TestBeanPostProcessor#postProcessAfterInitialization");
System.out.println(beanName);
return bean;
}
}
- 修改启动类:
package com.zhlab.ssm.demo.web;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @ClassName App
* @Description //App
* @Author singleZhang
* @Email 405780096@qq.com
* @Date 2021/1/19 0019 下午 3:02
**/
public class App {
public static void main(String[] args) throws ClassNotFoundException {
//XmlBeanFactory因为已经被废弃,这里使用了ClassPathXmlApplicationContext
//XmlBeanFactory使用方式如下:
// BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
}
}
- 运行main函数显示结果如下:
可以看到每个bean初始化前后都执行了postProcessBeforeInitialization、postProcessAfterInitialization方法。
那其中的执行顺序是如何的呢?
refresh方法中的registerBeanPostProcessors方法只是对这些BeanPostProcessors进行了注册,而执行的bean初始化是在refresh方法中的finishBeanFactoryInitialization方法里实现的。
这个具体在讲解finishBeanFactoryInitialization方法的时候展开讲,这里就引出来留个印象。其调用路径如下:
AbstractApplicationContext类的 finishBeanFactoryInitialization 方法
AbstractBeanFactory类的 getBean方法
AbstractBeanFactory类的 doGetBean方法
AbstractAutowireCapableBeanFactory类的 createBean方法
AbstractAutowireCapableBeanFactory类的 doCreateBean方法
AbstractAutowireCapableBeanFactory类的 initializeBean方法
看,最终来到AbstractAutowireCapableBeanFactory类的 initializeBean方法,这就是bean的初始化方法,AbstractAutowireCapableBeanFactory类是DefaultListableBeanFactory类的父类,我们知道在前面的执行过程中,创建的beanFactory是一个DefaultListableBeanFactory对象
我们具体来看bean初始化的时候执行了什么(见源码解析2):
【源码解析2】 initializeBean方法
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 注释1. securityManage 是一个安全管理器,判断其有无,然后执行实现了Aware系列接口的方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 如果没有 securityManage,方法里面校验了 bean 的类型,需要引用 Aware 接口
// 对特殊的 bean 处理:Aware/ BeanClassLoader / BeanFactoryAware
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 注释2. 调用已经注册好的 beanPostProcessor 的 postProcessBeforeInitialization 方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 注释3. 调用执行初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//注释4. 调用已经注册好的 beanPostProcessor 的 postProcessAfterInitialization 方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
从这里可以看出在bean执行初始化之前,会遍历所有已经注册好的 beanPostProcessor,并执行postProcessBeforeInitialization 方法;而在初始化之后会遍历所有已经注册好的 beanPostProcessor,并执行postProcessorAfterInitialization方法。
※好了其他的不在这里展开,以免对阅读顺序产生干扰,我们阅读源码时需要抓住主线走,等主线完成后,再回顾到做了标记的分支,逐个再击破。
总结
这里我们了解了registerBeanPostProcessors 方法,其主要是对各类BeanPostProcessors进行注册,围绕 BeanPostProcessor 接口,这里做的工作只是注册,具体实现在后边finishBeanFactoryInitialization方法才会使用到 这些BeanPostProcessor 接口的实现类。
postProcessBeforeInitialization、postProcessAfterInitialization方法分别在bean对象初始化的前后执行。
BeanPostProcessor 实现类和 BeanFactoryPostProcessor 实现类一样,也可以通过实现 PriorityOrdered、Ordered 接口来调整自己的优先级。
两者有些区别,注册BeanFactoryPostProcessor的实例,需要上下文执行refresh
BeanFactoryPostProcessor的处理对象时BeanFactory,它可以增强BeanFactory获取bean实例或定义等,并可以修改bean的属性,它发生在bean实例化之前,对bean的处理功能更强;BeanPostProcessor的处理对象时Bean,它体现的是AOP的思想,通过它来切入bean的初始化前后的增强处理,它默认是会对整个Spring容器中所有的bean进行处理,也可以自定义实现对某个bean的处理,它发生在bean实例化之后。