阅前提醒
全文较长,建议沉下心来慢慢阅读,最好是打开Idea,点开Spring源码,跟着下文一步一步阅读,更加便于理解。由于笔者水平优先,编写时间仓促,文中难免会出现一些错误或者不准确的地方,恳请各位大佬在评论区留言指正。建议在阅读本篇文章之前,先看下我的另一篇博文 一图助你搞明白Spring应用上下文初始化流程! 从而对Spring应用上下文初始化过程有个大概了解。
如果各位小伙伴由于笔者描述不清,而不理解的地方也欢迎在评论区留言哦!该系列文章共有三篇,敬请期待~ ~ ~
正文
一切的开始要从AbstractApplicationContext的refresh方法说起。refresh方法是应用上下文中最重要的方法,没有之一!
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 忽略其他方法...
try {
// 忽略其他方法...
// 调用所有实现了BeanFactoryPostProcessor接口的实现类.
invokeBeanFactoryPostProcessors(beanFactory);
// 其它方法忽略....
}
catch (BeansException ex) {
// 忽略其他方法...
throw ex;
}
finally {
resetCommonCaches();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
将包路径变为IoC容器中的BeanDefinition,对于注解驱动的应用上下文来说这一步需要等到refresh方法执行invokeBeanFactoryPostProcessors方法(XML驱动的应用上下文不是在这一步,而是在obtainFreshBeanFactory方法中)。
该方法由AbstractApplicationContext实现,调用BeanFactoryPostProcessor实现类的任务委派给了PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法完成。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 调用BeanFactoryPostProcessor接口及其子接口BeanDefinitionRegistryPostProcessor
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
BeanFactoryPostProcessor接口是独立于大名鼎鼎的BeanPostProcessor接口之外的一套接口。顾名思义是在BeanFactory实例化之后做一些事情。其子接口BeanDefinitionRegistryPostProcessor是用来向BeanFactory中注册BeanDefinition,该接口最重要的实现便是ConfigurationClassPostProcessor类。
这是IoC容器中最重要的类之一,因为在该类(ConfigurationClassPostProcessor)中完成了从包路径到IoC容器中的BeanDefinition的转换过程。
BeanFactoryPostProcessor中定义postProcessoBeanFactory方法,BeanDefinitionRegistryPostProcessor除了继承BeanFactoryPostProcessor的postProcessBeanFactory之外,还定义了自己的postProcessBeanDefinitionRegistry方法。
这里说一下这两个方法的调用时机,IoC容器是先调用postProcessBeanDefinitionRegistry方法再去调用postProcessBeanFactory方法。也就是说往IoC容器中注册BeanDefinition是早于对BeanFactory进行自定义操作的。这一点可以在PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法中得到体现。
在该方法中最先处理的BeanDefinitionRegistryPostProcessors实现类是调用该方法时传递的beanFactoryPostProcessors集合,那么这些实现类是从哪里获取的?
这些实现类是在创建Spring应用上下文时,通过调用Spring应用上下文的addBeanFactoryPostProcessors方法传递的。因此可以得知通过该方法添加的BeanFactoryPostProcessor实现类会最先被执行。
// 创建注解驱动Spring应用上下文
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext();
applicationContext.register(ApplicationConfig.class);
// 手动往Spring 应用上下文添加BeanFactoryPostProcessor接口实现类
applicationContext.addBeanFactoryPostProcessor(new MyBeanDefinitionRegistryPostProcessor());
applicationContext.refresh();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
// 判断beanFactory 是否是 BeanDefinitionRegistry类型的,DefaultListableBeanFactory实现了该接口
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 首先执行用户通过ConfigurableBeanFactory#addBeanPostProcessor方法添加的BeanFactoryPostProcessor实现类的postProcessBeanDefinitionRegistry方法
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 使用IoC容器来获取所有的 BeanDefinitionRegistryPostProcessor 接口实现类,通常获取到的只有ConfigurationClassPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 判断获取到的BeanDefinitionRegistryPostProcessor接口实现类是否实现了PriorityOrdered接口 这涉及优先级问题 PriorityOrdered-> Ordered -> 未实现
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 执行 获取到实现了BeanDefinitionRegistryPostProcessor接口以及PriorityOrdered接口实现类的postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 获取IoC容器中所有BeanDefinitionRegisterPostProcess接口实现类,然后判断是否实现了 Orderd接口 。为什么还要再次去IoC容器获取BeanDefinitionRegistryPostProcessor接口实现类,而不是使用前面获取到的?这是因为为了防止用户在BeanDefinitionRegistryPostProcessor接口实现类中又注册了BeanDefinitionRegistryPostProcessor接口实现类,这种情况
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);