Spring版本:5.2.9
首先附张IOC容器初始化的概述图,先有个大体画面:
图中可以看到
BeanDefinitionRegistryPostProcessor
与
BeanFactoryPostProcessor
在
BeanDefinition
加载之后,Bean实例化之前执行。
BeanDefinitionRegistryPostProcessor
该接口扩展了BeanFactoryPostProcessor
接口用于对BeanDefinitionRegistry
做进一步的处理。
当容器注册了所有的BeanDefinition
之后,会调用当前上下文中注册的BeanDefinitionRegistryPostProcessor
做进一步的处理。
示例
public class MyBeanFactoryDefinitionPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("MyBeanFactoryDefinitionPostProcessor#postProcessBeanDefinitionRegistry: 注册 book BeanDefinition...");
GenericBeanDefinition bookBeanDefinition = new GenericBeanDefinition();
bookBeanDefinition.setBeanClass(Book.class);
bookBeanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
Properties properties = new Properties();
properties.setProperty("name", "《java入门》");
properties.setProperty("author", "baiyang");
bookBeanDefinition.setPropertyValues(new MutablePropertyValues(properties));
registry.registerBeanDefinition("book", bookBeanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
for (String beanName : beanFactory.getBeanDefinitionNames()) {
System.out.println(beanFactory.getBeanDefinition(beanName));
}
}
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
context.addBeanFactoryPostProcessor(new MyBeanFactoryDefinitionPostProcessor());
context.refresh();
}
}
class Book {
private String name;
private String author;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
'}';
}
}
源码分析
首先是Spring的初始化经典方法refresh,所有的BeanFactory后处理器调用在图中所框出部分。
org.springframework.context.support.AbstractApplicationContext#refresh
org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors
如上图,执行Bean容器后处理器的动作是委派给PostProcessorRegistrationDelegate
类来执行的。并且传入了AbstractApplicationContext#getBeanFactoryPostProcessors()
返回的容器后处理器列表。
也就是说,通过AbstractApplicationContext#addBeanFactoryPostProcessor()
方法注册的BeanFactory后处理器需要在调用上下文的refresh
函数之前才可以。
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()
通过上述源码可以发现,在执行BeanDefinitionRegistryPostProcessor
的时候会经历以下过程:
1、首先执行通过方法传入的BeanDefinitionRegistryPostProcessor
2、执行实现PriorityOrdered
接口的BeanDefinitionRegistryPostProcessor
3、执行实现Ordered
接口的BeanDefinitionRegistryPostProcessor
4、最后执行没有优先级设置的BeanDefinitionRegistryPostProcessor
以上4个过程中会反复从beanFactory获取注册BeanDefinitionRegistryPostProcessor
类型的Bean,是因为在执行BeanDefinitionRegistryPostProcessor
本身的过程中可能会再次注册新的BeanDefinitionRegistryPostProcessor
类型的BeanDefinition
,所以需要每次执行完一次BeanDefinitionRegistryPostProcessor
就再次获取最新的Bean列表来筛选出还没有执行过的BeanDefinitionRegistryPostProcessor
。
BeanFactoryPostProcessor
BeanFactoryPostProcessor
与BeanDefinitionRegistryPostProcessor
的处理时机都发生在所有BeanDefinition
全部加载完毕后,完成单例Bean实例化之前。
但BeanFactoryPostProcessor
比BeanDefinitionRegistryPostProcessor
后执行,两者的区别是:BeanDefinitionRegistryPostProcessor
用于对已完成初步加载的BeanDefinitionRegistry
做进一步的后置处理;而BeanFactoryPostProcessor
用于对当前的已完成BeanDefinition
的BeanFactory
做进一步处理,两者处理的对象不同。
BeanDefinitionRegistryPostProcessor
本身是BeanFactoryPostProcessor
的扩展,所以BeanDefinitionRegistryPostProcessor
对象自身也是一个BeanFactoryPostProcessor
。
示例
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor#postProcessBeanFactory------------------");
for (String beanName : beanFactory.getBeanDefinitionNames()) {
System.out.println(beanFactory.getBeanDefinition(beanName));
}
}
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
GenericBeanDefinition bookBeanDefinition = new GenericBeanDefinition();
bookBeanDefinition.setBeanClass(Book.class);
bookBeanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
Properties properties = new Properties();
properties.setProperty("name", "《java入门》");
properties.setProperty("author", "baiyang");
bookBeanDefinition.setPropertyValues(new MutablePropertyValues(properties));
context.registerBeanDefinition("book", bookBeanDefinition);
context.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
context.refresh();
System.out.println(context.getBean(Book.class));
}
}
class Book {
private String name;
private String author;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
'}';
}
}
源码分析
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()
以上BeanFactoryPostProcessor
执行代码与BeanDefinitionRegistryPostProcessor
的执行代码同处于一个函数中;
执行过程与BeanDefinitionRegistryPostProcessor
相似:
1、执行实现PriorityOrdered
接口的BeanFactoryPostProcessor
2、执行实现Ordered
接口的BeanFactoryPostProcessor
3、最后执行没有优先级设置的BeanFactoryPostProcessor