首先我们关注一下Spring IoC容器的主要启动过程:Spring的ContextLoaderListener收到Tomcat容器启动完成的消息,初始化SpringIoC容器,开始执行refresh()。refresh()第2步(其他步骤先省略,下文会细说)会调用XmlBeanDefinitionReader读取Xml方式配置的BeanDefinition并注册,第5步会调用BeanFactory后处理器,例如调用ConfigurationClassPostProcessor这个BeanFactory后处理处理标注有@Configuration类的@Import、@Bean、@ComponentScan,调用MapperScannerConfiguration这个BeanFactory后处理Mybatis配置的Dao类。下面是这个关键过程的时序图:
1 启动过程
Spring IoC容器启动过程定义在接口ConfigurableApplicationContext.refresh()中,在AbstractApplicationContext中实现,源码:
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) { //启动前加锁同步
this.prepareRefresh(); //1.准备启动,准备PropertySource,校验必备配置
//2.新建BeanFactory并初始化,如果是Xml配置方式,这一步会载入BeanDefinition
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//3.设置BeanFactory的ClassLoader,Environment,BeanFactory后处理器
this.prepareBeanFactory(beanFactory);
try {
//4.属于第3步的补充操作,内部逻辑相似
this.postProcessBeanFactory(beanFactory);
//5.调用【BeanFactory后处理器】,对BeanDefinition进行加工。如果是注解配置,会在这
//一步载入BeanDefinition,而第2步就不会有载入动作
this.invokeBeanFactoryPostProcessors(beanFactory);
//6.注册【Bean后处理器】,这些后处理器是监听器,它们接收容器事件,监听到容器事件后
//有2个会在Bean初始化前后自动调用的方法
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource(); //7.初始化MessageSource
this.initApplicationEventMulticaster(); //8.初始化容器事件广播器
this.onRefresh(); //9.初始化容器,抽象方法,在子类中实现
this.registerListeners(); //10.注册监听器
//11.完成BeanFactory初始化,实例化所有非lazy-init的Bean
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh(); //12.完成初始化
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}//捕获到异常
this.destroyBeans(); //销毁Bean
this.cancelRefresh(var9); //取消容器的初始化
throw var9; //重新抛出异常
} finally {
this.resetCommonCaches();
}
}
}
2 解析初始化步骤
接下来重点分析上面每一步的具体工作,下面贴出来的源码会删去一些对我们理解Ioc容器无关紧要的内容。
2.1 prepareRefresh()
准备启动,准备启动所需的配置(PropertySource),验证属性是否都存在,设置早期监听器和早期事件收集集合。
protected void prepareRefresh() {
//【删】设置启动时间戳,关闭状态=false,活动状态=true
this.initPropertySources(); //初始化所有带占位符配置文件
this.getEnvironment().validateRequiredProperties(); //验证所有必需属性
//允许应用启动之前的事件,当multicaster一旦可用的时候立刻响应发布的事件
if (this.earlyApplicationListeners == null) {
//添加早期监听器
this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners);
} else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
//创建收集早期事件的集合
this.earlyApplicationEvents = new LinkedHashSet();
}
2.2 obtainFreshBeanFactory()
刷新BeanFacotry并返回。refreshBeanFactory包括创建BeanFactory对象(并可能加载类信息)。这一步和2.5有一些关联:在Xml配置方式下,Xml文件以IO流的形式读取,解析出Dom文档,BeanDefinition会通过<bean id="" class=""...>信息载入,随后进行注册。而如果是Springboot注解方式下,这一步不会有载入动作,会使用ConfigurationClassPostPorcessor扫描ClassPath,然后载入BeanDefinition,注册。
//刷新并获取BeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
this.refreshBeanFactory(); //启动BeanFactory ?
return this.getBeanFactory(); //返回BeanFactory
}
/*
* 初始化ApplicationContext,不同的ApplicationContext有不同实现,下面是①AbstractRefreshable-
* ApplicationContext的实现,在②GenericApplicationContext中仅仅设置了序列化Id
**/
protected final void refreshBeanFactory() throws BeansException {
if (this.hasBeanFactory()) {
this.destroyBeans();
this.closeBeanFactory(); //BeanFactory存在则关闭
}
try {
DefaultListableBeanFactory beanFactory = this.createBeanFactory();//新建BeanFactory
beanFactory.setSerializationId(this.getId());
this.customizeBeanFactory(beanFactory); //允许修改BeanFactory
this.loadBeanDefinitions(beanFactory); //加载BeanDefinition
Object var2 = this.beanFactoryMonitor;
synchronized(this.beanFactoryMonitor) { //加锁,设置BeanFactory
this.beanFactory = beanFactory;
}
} catch (IOException var5) {
throw new ApplicationContextException("I/O error parsing bean definition source for 。。。 ");
}
}
/*
* 在 XmlWebApplicationContext中的实现,初始化beanDefinitionReader并加载类信息
*/
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//使用XmlBeanDefinitionReader读取Bean信息
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
this.initBeanDefinitionReader(beanDefinitionReader);
//加载类信息,深入下去
this.loadBeanDefinitions(beanDefinitionReader);
}
/**
* XmlWebApplicationContext.loadBeanDefinitions(),循环根据配置文件加载类信息
*/
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
//Locations是classpath*下的配置文件:applicationContext.xml,servlet.xml等
String[] configLocations = this.getConfigLocations();
if (configLocations != null) {
String[] var3 = configLocations;
int var4 = configLocations.length;
for(int var5 = 0; var5 < var4; ++var5) {//循环读取配置文件
String configLocation = var3[var5];
//加载类信息
reader.loadBeanDefinitions(configLocation);
}
}
}
/**
* AbstractBeanDefinitionReader.loadBeanDefinitions(),对配置文件进行合理编码后加载类信息,有 删减
*/
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = this.getResourceLoader();
//Resource包含配置文件完整URL路径,如:URL
//[file:/E:/projects/spring_mybatis/out/artifacts/spring_atis_war_exploded/WEB-
//INF/classes/applicationContext.xml]
Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
//加载类信息
count = this.loadBeanDefinitions(resources);
。。。。
}
/**
* XmlBeanDefinitionReader.loadBeanDefinitions(),encodedResource是编码后的配置文件,有删减
*/
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
//IO流读取配置文件
InputStream inputStream = encodedResource.getResource().getInputStream();
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
。。。 接下来为了节省篇幅,把重要的/跨多个方法的内容写在一起。。。
//加载配置文件形成包含节点的xml文档
Document doc = doLoadDocument(inputSource, resource);
int count = registerBeanDefinitions(doc, resource);
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
doRegisterBeanDefinitions(doc.getDocumentElement());
}
最后,我们有必要看一下BeanDefinition的注册(注册的通俗含义就是找个东西把它装起来),看一下注册位置和注册方式:
/**
* 出自DefaultListableApplicationContext,beanDefinitionMap定义是:
* private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentH-
* ashMap<>(256);
*/
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
if(.....省略....){
// 注册位置
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
if (hasBeanCreationStarted()) {
synchronized (this.beanDefinitionMap) {
// 注册位置
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// 注册位置
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
}
2.3 prepareBeanFactory()
设置BeanFactory的ClassLoader,Environment,Bean后处理器,添加自动注入忽略类等。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.setBeanClassLoader(this.getClassLoader()); //设置类装载器
//表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//注册属性编辑器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));//添加Bean后处理器
beanFactory.ignoreDependencyInterface(EnvironmentAware.class); //依赖注入时忽略该类
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); //依赖注入时注入该对象
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
if (beanFactory.containsBean("loadTimeWeaver")) { //如果支持AspectJ
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); //注册载入时增强处理器
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
//创建3个单例配置文件
if (!beanFactory.containsLocalBean("environment")) {
beanFactory.registerSingleton("environment", this.getEnvironment());
}
if (!beanFactory.containsLocalBean("systemProperties")) {
beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean("systemEnvironment")) {
beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
}
}
2.4 postProcessBeanFactory()
在Xml方式下这是一个空方法。我们看一下另一个实现中GenericWebApplicationContext中实现了什么功能:
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
if (this.servletContext != null) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
}
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
}
可以看到和2.3 prepareBeanFactory()提供了一样的功能,算是对它的功能进行了补充和定制化。
2.5 invokeBeanFactoryPostProcessors()
这一步是调用所有【BeanFactory后处理器】。Springboot注解配置情况下,这一步才是载入-解析-注册BeanDefinition的地方,做出这一动作的是ConfigurationClassPostProcessor,它的内部有一个ComponentScanParser对src.java.com.xxx包进行扫描,读取所有类信息形成BeanFefinition(不论这些类有没有任何注解)。另外,这一步还有一个叫做PropertySourcesPlaceholderConfigurer的BeanFactory后处理器,这个处理器初始化一个PropertySourcesPlaceholder-Configurer,它就是加载application.properties的类(加载***.yml配置文件的是YamlPropertiesFactoryBean),PropertySourcesPlaceholderConfigurer会按优先级保存在PropertySourcesPlaceholderConfigurer的MutablePropertySources类型的属性中。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//重点在这里面,这个方法很长?
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory
//下面的getBeanFactoryPostProcessors()获取【BeanFactory后处理器】
,this.getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
/**
* 调用【BeanFactory后处理器】,这种处理器主要是对BeanDefinition进行加工,加工动作在所有bean实
* 例化之前,保证所有Bean实例化前都可以得到处理。注意把【BeanFactory后处理器】和下一节的【Bean
* 后处理器】区别开,Bean后处理器类似监听器,在监听到容器事件时发挥作用,而且是在Bean实例化前后
*/
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet();
ArrayList regularPostProcessors;
ArrayList registryProcessors;
int var9;
ArrayList currentRegistryProcessors;
String[] postProcessorNames;
if (beanFactory instanceof BeanDefinitionRegistry) { //大IF开始,如果此BeanFactory属于BeanDefinitionRegistry的实例,则它用于处理BeanDefinition
BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
regularPostProcessors = new ArrayList();
registryProcessors = new ArrayList();
Iterator var6 = beanFactoryPostProcessors.iterator();
while(var6.hasNext()) { //循环处理所有BeanFactory后处理器
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
//如果该后处理器属于BeanDefinitionRegistryPostProcessor的实例
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
//把该BeanDefinition后处理器注册到BeanFactory
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);//标记该后处理器为已注册后处理器
} else {
regularPostProcessors.add(postProcessor);//否则标记为普通后处理器
}
}
currentRegistryProcessors = new ArrayList();
//1.取出刚才的BeanFactory中已注册的【BeanDefinitionRegistryPostProcessor】型
//BeanFactory后处理器的名称,本次处理有优先排序标记的后处理器
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];
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { //如果该处理器有优先排序标记
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); //标记为当前需处理的后处理器
processedBeans.add(ppName); //该后处理器本身标记为已加载的Bean
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory); //对处理器进行优先级排序
registryProcessors.addAll(currentRegistryProcessors);
//在registry(上面的BeanFactory)中调用当前需处理的后处理器
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear(); //调用完成,清空当前需处理的后处理器
//2.再次取出BeanFactory中已注册的BeanDefinition后处理器的名称,本次处理有排序标记的处理器
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
var16 = postProcessorNames;
var9 = postProcessorNames.length;
for(var10 = 0; var10 < var9; ++var10) { //循环处理所有取出的后处理器名称
ppName = var16[var10];
//如果该后处理器没有加载过并且有排序标记(优先级低于上面的“PriorityOrdered”)
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);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
boolean reiterate = true;
while(reiterate) {
reiterate = false;
//3.调用所有剩下的BeanDefinition后处理器,还是要先优先级排序,防止上述过程中有新的带排
//序标记的处理器加入
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
String[] var19 = postProcessorNames;
var10 = postProcessorNames.length;
for(int var26 = 0; var26 < var10; ++var26) {
String ppName = var19[var26];
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();
}
//依次调用所有已注册BeanDefinition后处理器/常规BeanDefinition后处理器
invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
} else { //大IF结束,否则直接调用所有后处理器
invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
}
//4.后面所有代码:取出所有【BeanFactoryPostProcessor】类型后处理器(注意前面是
//【BeanDefinitionRegistryPostProcessor】类型后处理器),按照上述步骤,先处理有优先排序标
//记的,再处理有排序标记的,最后是无标记的
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();
}
小结一下:这一步总体是在按照先BeanDefinitionRegistryPostProcessor后BeanFactoryPostProcessor,先高优先级再低优先级的顺序调用后处理器。重点还是在调用后处理器的方法这一步:invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); 我们看看这一步到底在搞什么名堂。
private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
Iterator var2 = postProcessors.iterator();
while(var2.hasNext()) {
BeanDefinitionRegistryPostProcessor postProcessor = (BeanDefinitionRegistryPostProcessor)var2.next();
//循环所有后处理器,重点在这里?
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
略去中间的跳转过程,来到最终的ConfigurationClassPostProcessor.processConfigBeanDefinitions()方法中,比较长,我们耐心看下去:
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
//待处理类集合,注意里面装的是BeanDefinitionHolder,其中的BeanDefinition是要处理的对象。
List<BeanDefinitionHolder> configCandidates = new ArrayList();
//取出registry(也就是BeanFactory)中的所有BeanDefinition名称
String[] candidateNames = registry.getBeanDefinitionNames();
String[] var4 = candidateNames;
int var5 = candidateNames.length;
for(int var6 = 0; var6 < var5; ++var6) { //循环名称并取出BeanDefinition
String beanName = var4[var6];
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (!ConfigurationClassUtils.isFullConfigurationClass(beanDef) && !ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
//如果没有完成配置(FullConfig),加入待处理类列表
if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
} else if (this.logger.isDebugEnabled()) {
this.logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
if (!configCandidates.isEmpty()) {
//按@Order注解进行排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
SingletonBeanRegistry sbr = null;
//设置Bean实例名称生成器
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry)registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator)sbr.getSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator");
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
//检查环境配置
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
//主角登场,@Configuration注解解析器
ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//用Set除重
Set<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates);
HashSet alreadyParsed = new HashSet(configCandidates.size());
do {
//重中之重,解析BeanDefinition,我们接下来进去看一下
parser.parse(candidates);
//校验
parser.validate();
//ConfigurationClass包含以上两步解析完成的多个Bean的定义信息
Set<ConfigurationClass> configClasses = new LinkedHashSet(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
//Bean信息读取器,该Rreader可以把ConfigurationClass中的Bean信息读取出来,
//并注册bean定义到容器
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry());
}
//注册
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses); //标记为已处理
candidates.clear(); //清空待处理
//如果有新的BeanDefinition信息加入到BeanRegistry
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet();
Iterator var12 = alreadyParsed.iterator();
while(var12.hasNext()) {
ConfigurationClass configurationClass = (ConfigurationClass)var12.next();
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
String[] var23 = newCandidateNames;
int var24 = newCandidateNames.length;
//如果新加入的类没有被处理过,加入待处理类集合
for(int var14 = 0; var14 < var24; ++var14) {
String candidateName = var23[var14];
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
} while(!candidates.isEmpty()); //循环直到没有新的类信息需要处理
//把ImportRegistry注册为单例模式,用来支持importAware
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
//清除metadataReaderFactory 缓存
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory)this.metadataReaderFactory).clearCache();
}
}
}
小结:这一节的主要内容是,BeanFactory对其中的BeanDefinition后处理器和BeanFactory后处理器两种后处理器进行排序调用,对Bean进行一些处理。我们看过了ConfigurationClassPostProcessor对Spring注解的处理,对这句话也有了更深的认识,“Java注解本身只是一个信息标记,要发挥其作用,必须要有一段对应的处理代码”。
2.6 registerBeanPostProcessors()
注册Bean后处理器(BeanPostPorcessor),这些后处理器类似监听器,会在收到相应的容器事件时发挥作用,BeanPostPorcessor接口有两个方法:postProcessBeforeInitialization(Object bean,String beanName)和postProcessAfterInitialization(Object bean, String),这两个方法在初始化bean前后执行。这一步有一个叫做ConfigurationPropertiesBindingPostProcessor的后处理器,专门用于@ConfigurationProperties注解,把application.properties中的配置绑定到对应bean的对应属性中。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//取出所有后处理器名称
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 把实现了PriorityOrdered接口的后处理器按优先级区分开
// 按照常规的(internal)/有排序的/无排序的分开
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 首先注册实现了PriorityOrdered接口的
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);
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 然后是实现了Ordered接口的
List<BeanPostProcessor> 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);
// 接下来是所有无排序的
List<BeanPostProcessor> 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);
// 最后是常规的
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
//注册ApplicationListenerDetector,用来检查所有的ApplicationListener,它处于处理器链末端。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
2.7 initMessageSource
初始化MessageSource Bean,国际化。
/**
* 初始化消息源
*/
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// 给MessageSource设置父级MessageSource
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// 创建一个空的MessageSource
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
2.8 initApplicationEventMulticaster
初始化容器事件广播电台(内部是一个装有Listener的Set和一个线程池,需要通知时,依次异步通知对监听了这种事件的监听器)。
/**
* 从BeanFactory取出或创建新的广播器并设置到当前ApplicationContext
*/
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//从BeanFactory获取
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("");
}
}
else { //没有则新建
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("");
}
}
}
2.9 onRefresh()
用于创建特殊Bean的模板方法,默认没有任何操作。
2.10 registerListeners()
注册监听器,发布早期积累的容器事件,ApplicationMutiCaster内部有一个线程池和Set<Listener>,发布事件时会筛选监听了当前事件的监听器,然后调用监听器异步执行。
/**
* 注册实现了ApplicationListener接口的监听器Bean,其他非Bean的监听器也可以注册但不推荐。
*/
protected void reApplicationgisterListeners() {
// 首先注册BeanFactory中指定的监听器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 通过ClassName注册其他监听器,但不要在这里初始化非监听器的类
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 把早期积累的事件广播出去
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
2.11 finishBeanFactoryInitialization()
完成容器的初始化,使用BeanDefinition创建所有非懒加载的Bean(懒加载:lazy-init,标注有@Lazy的就是懒加载)。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化容器的conversionService.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
//给没有Bean后处理器的Bean添加一个默认的内置的占位符处理器,处理@Vaule、@Configuratio-
//nProperties和从注解取值
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 实例化运行时增强Bean,使得AOP增强处理器可以更早注册进来.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用临时类加载器做类型判断.
beanFactory.setTempClassLoader(null);
// 冻结beandefinition信息,防止更改beandefinition.
beanFactory.freezeConfiguration();
// 实例化所有非懒加载Bean
beanFactory.preInstantiateSingletons();
}
2.12 finishRefresh()
完成容器刷新。
protected void finishRefresh() {
// 清除容器加载BeanDefinition过程中保存的资源(Resource)
clearResourceCaches();
// 初始化生命周期处理器
initLifecycleProcessor();
// 刷新生命周期处理器
getLifecycleProcessor().onRefresh();
// 发布ContextRefreshedEvent事件
publishEvent(new ContextRefreshedEvent(this));
// 注册快照,用于保存Bean和Bean依赖关系的快照
LiveBeansView.registerApplicationContext(this);
}
这篇文章解析了Spring容器启动过程,详细叙述了BeanDefinition的载入-解析-注册过程,但IoC的关键动作“依赖注入”还没有涉及,我们在下一篇文章中对源码进行解读。