本文仍然以ClasspathXmlApplicationContext为入口进行记录,通过之前对Spring的学习,我们已知ClasspathXmlApplicationContext构造方法中调用的this.refresh()方法是整个Spring容器初始化的核心方法,refresh()方法调用过程如下:
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
//重要方法1
this.invokeBeanFactoryPostProcessors(beanFactory);
//重要方法2
this.registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var10) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
}
this.destroyBeans();
this.cancelRefresh(var10);
throw var10;
} finally {
this.resetCommonCaches();
contextRefresh.end();
}
}
}
一、invokeBeanFactoryPostProcessors(beanFactory)
进入refresh()方法,先来看这个方法调用:this.invokeBeanFactoryPostProcessors(beanFactory);这个方法的作用顾名思义,就是调用BeanFactory中存在的BeanFactoryPostProcessor,该方法实现了在Spring 启动期间,能够对BeanDefinition进行操作。在该方法内部又调用了这个方法:PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());核心操作都在这个方法里,具体实现如下:
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet();
ArrayList regularPostProcessors;
ArrayList registryProcessors;
int var9;
ArrayList currentRegistryProcessors;
String[] postProcessorNames;
//判断BeanFactory是否是BeanDefinitionRegistry类型,如果是,走下面的逻辑
//通过继承关系可以看出,BeanFactory就是BeanDefinitionRegistry类型
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
regularPostProcessors = new ArrayList();
registryProcessors = new ArrayList();
//此处beanFactoryPostProcessors集合为空,因为此时还没有BeanFactoryPostProcessor加入到这个集合中。
Iterator var6 = beanFactoryPostProcessors.iterator();
//由于beanFactoryPostProcessors集合为空,因此这段while逻辑不会执行
while(var6.hasNext()) {
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
currentRegistryProcessors = new ArrayList();
//获取BeanFactory中类型是BeanDefinitionRegistryPostProcessor的类名
//这里是能获取到有且只有一个,刚好是在前面<component-scan>标签解析最后,执行注册组件操作中加入到BeanDefinitionRegsitry中的ConfigurationClassPostProcessor
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
String[] var16 = postProcessorNames;
var9 = postProcessorNames.length;
int var10;
String ppName;
for(var10 = 0; var10 < var9; ++var10) {
ppName = var16[var10];
//判断当前的BeanPostProcessor是否是PriorityOrdered类型
//ConfigurationClassPostProcessor实现了PriorityOrdered接口,因此会进入这个if块
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//进入if后,调用beanFactory.getBean()提前将ConfigurationClassPostProcessor实例化
//将实例加入到了currentRegistryProcessors集合中
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//对BeanFactoryPostProcessor进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//执行BeanDefinitionRegistryPostProcessor接口提供的postProcessBeanDefinitionRegistry()方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
var16 = postProcessorNames;
var9 = postProcessorNames.length;
for(var10 = 0; var10 < var9; ++var10) {
ppName = var16[var10];
//继续判断BeanPostProcessor是否实现了Ordered接口
//ConfigurationClassPostProcessor没有实现Ordered接口,因此不会加入currentRegistryProcessors集合
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//processedBeans记录了已经处理过的类
processedBeans.add(ppName);
}
}
//此时currentRegistryProcessors集合中为空
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
boolean reiterate = true;
while(reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
String[] var19 = postProcessorNames;
var10 = postProcessorNames.length;
for(int var26 = 0; var26 < var10; ++var26) {
String ppName = var19[var26];
//剩下的就是既没有实现PriorityOrdered接口,也没有实现Ordered接口的类
//且不在processedBeans集合中,意味着在前面没有处理过,在这里处理
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
//BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry()方法执行完了
//接下来就是执行BeanFactoryPostProcessor中的postProcessBeanFactory()方法
//由于BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,因此这个类里也有这个方法
invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
} else {
invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
}
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
regularPostProcessors = new ArrayList();
registryProcessors = new ArrayList();
currentRegistryProcessors = new ArrayList();
postProcessorNames = postProcessorNames;
int var20 = postProcessorNames.length;
String ppName;
for(var9 = 0; var9 < var20; ++var9) {
ppName = postProcessorNames[var9];
if (!processedBeans.contains(ppName)) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
regularPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
registryProcessors.add(ppName);
} else {
currentRegistryProcessors.add(ppName);
}
}
}
sortPostProcessors(regularPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList();
Iterator var21 = registryProcessors.iterator();
while(var21.hasNext()) {
String postProcessorName = (String)var21.next();
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList();
Iterator var24 = currentRegistryProcessors.iterator();
while(var24.hasNext()) {
ppName = (String)var24.next();
nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
beanFactory.clearMetadataCache();
}
上面方法的核心就是实例化容器中的BeanFactoryPostProcessor,此时是BeanDefinitionRegistryPostProcessor,实际上就是之前在注册组件时加入进来的ConfigurationClassPostProcessor,这个类会在后面基于注解的Spring初始化流程中重点说明,它实现了BeanDefinitionRegistryPostProcessor接口,并依次调用接口需要实现的两个方法,分别为:postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)和postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)。
这里需要着重记录的是,此处为Spring为我们提供的一个扩展点,即我们可以自己写一个类实现BeanDefinitionRegistryPostProcessor接口,并实现这两个方法,第一个方法传入了BeanDefinitionRegistry对象,我们知道这个对象为Spring的BeanDefinition注册器,能够对bd进行增删查改,这就使我们能够在程序启动过程中动态完成对某些bean的实例化或者修改操作。
例如:我们实现如下一个类:
/**
* 这是我们自己实现的一个类,实现了BeanDefinitionRegistryPostProcessor接口
*/
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
//首先会调到这个方法里,并传入了registry对象,该对象中提供了对bd的各种操作
//可以通过getBeanDefinition(String)方法获取某个待实例化类的bd对象,对里面的属性进行修改
BeanDefinition bd = registry.getBeanDefinition("student");
GenericBeanDefinition gbd = (GenericBeanDefinition) bd;
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.addPropertyValue("username" , "tom");
gbd.setPropertyValues(propertyValues);
//也可以new出一个bd对象,将某个类变为bd对象,这样在spring进行实例化的时候,就会把该对象也加入到spring容器中
//这样我们就又多了一种能够实例化springbean的方式,并且是在程序启动过程中动态生成的。
GenericBeanDefinition gbd2 = new GenericBeanDefinition();
gbd2.setBeanClass(Teacher.class);
propertyValues = new MutablePropertyValues();
propertyValues.addPropertyValue("name" , "Jerry");
propertyValues.addPropertyValue("age" , 33);
gbd2.setPropertyValues(propertyValues);
registry.registerBeanDefinition("teacher" , gbd2);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
//然后会调用到这个方法中,这个方法中传入了configurableListableBeanFactory对象
//其实这个类也是实现了BeanDefinitionRegistry接口。
}
}
二、registerBeanPostProcessors(beanFactory)
Spring容器初始化第二个重要的步骤,将BeanPostProcessor注册到BeanFactory中,BeanPostProcessor为我们提供了非常方便的扩展机制,在n个地方都为我们埋了扩展点,方便我们进行扩展。我们进入该方法,内部又进行了一步方法调用:PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);我们重点来看这个方法的实现过程:
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//首先获取所有beanFactory中实现了BeanPostProcessor接口的类名
//这里就是之前在注册组件时注册进来的两个分别为:
//AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//new出这几个list是为了后面排序做准备
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList();
List<BeanPostProcessor> internalPostProcessors = new ArrayList();
List<String> orderedPostProcessorNames = new ArrayList();
List<String> nonOrderedPostProcessorNames = new ArrayList();
String[] var8 = postProcessorNames;
int var9 = postProcessorNames.length;
String ppName;
BeanPostProcessor pp;
//遍历所有实现上面接口的类名
for(int var10 = 0; var10 < var9; ++var10) {
ppName = var8[var10];
//判断该类是否实现了PriorityOrdered接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//如果实现了PriorityOrdered接口,调用beanFactory.getBean()提前将该bean实例化,变为spring的bean
pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
//实现了PriorityOrdered接口的BeanPostProcessor实例都放到了priorityOrderedPostProcessors集合中
//两个BeanPostProcessor都实现了该接口,因此都被加入priorityOrderedPostProcessors集合
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//这两个BeanPostProcessor也都实现了MergedBeanDefinitionPostProcessor,因此也都被加入internalPostProcessors集合中
internalPostProcessors.add(pp);
}
//判断是否实现了Ordered接口,这里没有,因此这个集合是空的
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
//这个集合也是空的
nonOrderedPostProcessorNames.add(ppName);
}
}
//对上面两个进行排序,排序后common在前面,autowired在后面
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//按顺序注册到beanFactory中,其实就是在beanFactory内部维护了一个beanPostProcessors的list,此时注册BeanPostProcessor的工作已经完成。
registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
List<BeanPostProcessor> orderedPostProcessors = new ArrayList();
Iterator var14 = orderedPostProcessorNames.iterator();
//orderedPostProcessorNames这个集合是空的,因此不会走下面的循环
while(var14.hasNext()) {
String ppName = (String)var14.next();
BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList();
Iterator var17 = nonOrderedPostProcessorNames.iterator();
//这个集合也是空的,循环也不会走
while(var17.hasNext()) {
ppName = (String)var17.next();
pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
该方法执行后就完成了BeanPostProcessor的注册工作,此时只有两个,即代码注释中提到的,另外,这里只是BeanPostProcessor的注册,还没有调用,在后面的过程中,会在各种不同的时机,对不同类型的BeanPostProcessor进行调用。
还需要着重记录一下,这里便是Spring为我们提供的另一个扩展点,即自己写一个类实现BeanPostProcessor接口,BeanPostProcessor的子接口类型有很多,都是在不同的阶段调用的,在后面我们遇到的时候都会进行记录和总结,以便我们在今后的开发中能够灵活的对Spring进行扩展。