什么是ApplicationContext
在上一篇我们一直是以BranFactory接口以及它的默认实现类XMLBeanFactory为例进行分析,但是spring还提供了一个接口ApplicationContext,用于扩展BeanFactory现有的功能。我们先来看下类图
今天主要分析的是如何通过ApplicationContext来加载整个bean的流程。相信很多人都知道,是通过refresh()方法来开始加载加载整个bean的流程的,那我们来看这个方法,
它是位于spring-context模块下org.springframework.context.support目录下面。
再来看这个方法做了什么?我先贴上一段代码,附上一些简洁的注释,下面我们再重点讲一下里面的几个方法。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 准备刷新上下文的环境,例如对系统属性及环境变量的初始化及验证
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 初始化BeanFactory,并进行XML的读取;经过此函数后,ApplicationContext就已经拥有了BeanFactory的全部功能。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 对BeanFactory进行各种功能的填充
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 允许子类做额外的处理
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 激活BeanFactory处理器
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册拦截Bean创建的Bean处理器,这里只是注册,真正调用的时候是在getBean的时候
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 为上下文初始化Message源,即不同语言的消息体,国际化处理
initMessageSource();
// Initialize event multicaster for this context.
// 初始化应用消息广播器,并放入'applicationEventMulticaster' bean中
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 留给子类来初始化其他的Bean
onRefresh();
// Check for listener beans and register them.
// 在所有注册的bean中查找Listener bean,注册到消息广播器中
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 完成刷新过程,通知声明周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 结束刷新的过程
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
这段代码的风格绝对符合spring编码的规范,将每个步骤应该干的事情全部封装起来,让读者清晰的了解它整体的运行逻辑,来看第一个方法prepareRefresh(),
prepareRefresh()
这段代码就不附上具体的代码了,主要讲下具体的作用:主要就是做一些准备工作,例如容器状态设置、对系统属性及环境变量的初始化和验证,里面重点提2个方法
-
initPropertySources(),这个在AbstractApplicationContext中是一个空方法,没有任何逻辑,主要是给用户最大扩展Spring的能力。用户可以根据自身的需要重写 initPropertySources 方法,并在方法中进行个性化的属性处理及设置。
-
validateRequiredProperties(),是对属性进行验证。举个例子,代码在启动的时候需要依赖系统环境变量中的一些配置,而如果用户在系统变量中没有这个配置,那个代码就会抛异常。
obtainFreshBeanFactory()
这个方法的主要作用就是获取初始化BeanFactory,也就是获取Bean工厂
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//初始化BeanFactory,并进行XML文件读取,并将得到的BeanFacotry记录在当前实体的属性中
refreshBeanFactory();
// 返回当前beanFactory的属性
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
这里面重要的方法是refreshBeanFactory(),这个方法的主要最用就是创建DefaultListableBeanFactory,并设置序列化id,然后通过loadBeanDefinitions去解析出BeanDefinition,再使用全局的DefaultListableBeanFactory记录结果
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 创建DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
// 为了序列化指定id,如果需要的话,让这个BeanFactory从id反序列化到BeanFactory对象
beanFactory.setSerializationId(getId());
// 定制BeanFactory,设置相关属性,包括是否允许覆盖同名称下的不同定义的对象以及循环依赖以及
// 设置@Autowired 和 @Qualifier 注解解析器 QualifierAnnotationAutowireCandidateResolver
customizeBeanFactory(beanFactory);
// 初始化DocumentReader,并进行XML文件的读取以及解析
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
总结一下就是:
- 创建DefaultListableBeanFactory。在介绍BeanFactory的时候,声明方式为:BeanFactory bf = new XmlBeanFactory("beanFactoryTest.xml"),其中的XmlBeanFactory继承自DefaultListableBean Factory,并提供了XmlBeanDefinitionReader类型的reader属性,也就是说DefaultListableBeanFactory是容器的基础。必须首先要实例化,那么在这里就是实例化。
-
指定序列化ID。
-
定制BeanFactory。
-
加载BeanDefinition。
-
使用全局变量记录BeanFactory类实例。
因为DefaultListableBeanFactory类型的变量beanFactory是函数内的局部变量,所以要使用全局变量记录解析结果。
prepareBeanFactory()
进入函数prepareBeanFactory前,Spring已经完成了对配置的解析,而ApplicationContext在功能上的扩展也由此展开。这段代码比较长,但是里面的功能逻辑非常清晰,我们来看一下
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
//设置beanFactory的classLoader为当前context的classLoader
beanFactory.setBeanClassLoader(getClassLoader());
//设置beanFactory的表达式语言处理器,Spring3增加了表达式语言的支持,
//默认可以使用#{bean.xxx}的形式来调用相关属性值。
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//为beanFactory增加了一个默认的propertyEditor,这个主要是对bean的属性等设置管理的一个工具
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 添加BeanPostProcessor
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 设置了几个忽略自动装配的接口
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 interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
// 设置了几个自动装配的特殊规则
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
//增加对AspectJ的支持
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
看上面的注解其实也能大概明白其中的具体作用,我们也不必深入去了解,大致总结一下这块做的事情
- 增加对SPEL语言的支持。
- 增加对属性编辑器的支持。
- 增加对一些内置类,比如EnvironmentAware、MessageSourceAware的信息注入。
- 设置了依赖功能可忽略的接口。
- 注册一些固定依赖的属性。
- 增加AspectJ的支持(通过增加一些组件来实现)。
- 将相关环境变量及属性注册以单例模式注册。
postProcessBeanFactory()
这个方法正如我们最开始在注释中写的那样,主要是为了给子类中重写以便子类在BeanFactory创建完成后做进一步的操作,它本身是一个空的方法。
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
invokeBeanFactoryPostProcessors()
这个方法主要作用是调用BeanFactoryPostProcessors来处理一些定义bean的后置操作
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
首先我们先来看 getBeanFactoryPostProcessors()这个方法是如何获取到BeanFactoryProcessors的:对于硬编码注册的后处理器的处理,主要是通过AbstractApplicationContext中的添加处理器方法addBeanFactoryPostProcessor进行添加。ps:系统监听器启动的时候会添加BeanFactoryPostProcessor和配置文件加载玩后也会注添加一些BeanFactoryPostProcessor
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
this.beanFactoryPostProcessors.add(postProcessor);
}
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}
再来看最关键的方法:invokeBeanFactoryPostProcessors()这个方法很长,有180多行,这里就不全部展示,我们先来看一部分,再分析其具体的作用
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet<>();
//对BeanDefinitionRegistry类型的处理
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//对于BeanDefinitionRegistryPostProcessor类型,在BeanFactoryPostProcessor的基础上还有自己定义的方法,需要先调用
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
//记录常规BeanFactoryPostProcessor
regularPostProcessors.add(postProcessor);
}
}
...
}
else{
...
}
...
}
registryPostProcessors:记录通过硬编码方式注册的BeanDefinitionRegistryPostProcessor类型的处理器。
regularPostProcessors:记录常规BeanFactoryPostProcessor类型的处理器。
processedBeans:记录通过硬编码方式注册的BeanDefinitionRegistryPostProcessor类型的处理器。
registryProcessors:记录通过配置方式注册的BeanDefinitionRegistryPostProcessor类型的处理器。
这个记住这几个集合的作用。 再来看
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
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);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
上面这两段代码的意思是:
- 遍历bean,获取BeanDefinitionRegistryPostProcessor类型的bean,
- 如果有实现PriorityOrdered接口,就加入到currentRegistryProcessors列表中和processedBeans集合中
- 对currentRegistryProcessors处理器进行分类
- 加入到registryProcessors
- 循环currentRegistryProcessors列表,调用元素的postProcessBeanDefinitionRegistry方法
- 清除currentRegistryProcessors缓存
看源码我们会发现,接下来的好几个代码块全部都是和这部分代码一致,下面就是,如果有实现Ordered.class接口,则会安装上面的方式重新来一遍过程。再下面都是一些重复的过程,为什么要重复呢,因为spring要判断所有的BeanFactoryProcessors,每次重复都是内部判断条件不一致,避免遗漏。
用几张图来总结一下invokeBeanFactoryPostProcessors()方法:
这四张图基本说明了invokeBeanFactoryPostProcessors()方法的作用,主要就是避免遗漏对实现了BeanDefinitionRegistryPostProcessor接口的类的处理。到这里我们invokeBeanFactoryPostProcessors()方法就讲完了。
registerBeanPostProcessors();
现在我们来探索下BeanPostProcessor,但是这里并不是调用,而是注册。真正的调用其实是在 bean 的实例化阶段进行的。
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
registerBeanPostProcessors这个方法很长,这里我们不粘贴代码过来了,这个方法的主要作用为:
- 找到BeanPostProcessor的实现
- 排序后注册进容器
按照源码的步骤具体来看下:
//第一步,注册所有实现PriorityOrdered的BeanPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
//第二步,注册所有实现Ordered的BeanPostProcessor
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);
// Now, register all regular BeanPostProcessors.
//第三步,注册所有无序的BeanPostProcessor
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);
// Finally, re-register all internal BeanPostProcessors.
//第四步,注册所有MergedBeanDefinitionPostProcessor类型的BeanPostProcessor,并非重复注册,
//在beanFactory.addBeanPostProcessor中会先移除已经存在的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).
//添加ApplicationListener探测器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
首先我们会发现,对于 BeanPostProcessor 的处理与 BeanFactoryPostProcessor 的处理极为相似,但是似乎又有些不一样的地方。经过反复的对比发现,对于 BeanFactoryPostProcessor的处理要区分两种情况,一种方式是通过硬编码方式的处理,另一种是通过配置文件方式的处理
对于 BeanFactoryPostProcessor的处理,不但要实现注册功能,而且还要实现对后处理器的激活操作,所以需要载入配置中的定义,并进行激活;而对于BeanPostProcessor并不需要马上调用,再说,硬编码的方式实现的功能是将后处理器提取并调用,这里并不需要调用,当然不需要考虑硬编码的方式了,这里的功能只需要将配置文件的BeanPostProcessor提取出来并注册进入beanFactory就可以了。
对于 BeanFactoryPostProcessor的处理,不但要实现注册功能,而且还要实现对后处理器的激活操作,所以需要载入配置中的定义,并进行激活;而对于BeanPostProcessor并不需要马上调用,再说,硬编码的方式实现的功能是将后处理器提取并调用,这里并不需要调用,当然不需要考虑硬编码的方式了,这里的功能只需要将配置文件的BeanPostProcessor提取出来并注册进入beanFactory就可以了。
对于 beanFactory 的注册,也不是直接注册就可以的。在 Spring 中支持对于 BeanPost Processor的排序,比如根据PriorityOrdered进行排序、根据Ordered进行排序或者无序,而Spring在BeanPostProcessor的激活顺序的时候也会考虑对于顺序的问题而先进行排序。
initMessageSource()
初始化国际化相关的属性,会先判断bean工厂是否包含国际化的BeanName,没有的话就会创建一个
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isDebugEnabled()) {
logger.debug("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
"': using default [" + this.messageSource + "]");
}
}
}
initApplicationEventMulticaster()
初始化事件广播器,注册到容器当中,逻辑很简单,spring的事件监听的用法就不再描述,不清楚的同学可以去看下 ApplicationEvent和ApplicationListener的简单实现
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
当产生 Spring 事件的时候会默认使用 SimpleApplicationEventMulticaster 的multicastEvent来广播事件,遍历所有监听器,并使用监听器中的onApplicationEvent方法来进行监听器的处理。而对于每个监听器来说其实都可以获取到产生的事件,但是是否进行处理则由事件监听器来决定。
onRefresh()
这个方法也是一个空实现,和之前讲的initPropertySources()方法一样,是留给子类实现的,此处是的作用是留给子类来初始化其他的Bean;对于web容器内的实现是createWebServer,如tomcat。
registerListeners()
注册监听器:1.添加容器内的监听事件器至事件广播器中,2.广播早期注册到applicationEventMulticaster的事件
protected void registerListeners() {
// Register statically specified listeners first.
// 硬编码的方式注册的监听器处理
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
// 配置文件注册的监听器处理
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
finishBeanFactoryInitialization()
完成BeanFactory的初始化工作,其中包括ConversionService的设置、配置冻结以及非延迟加载的bean的初始化工作。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
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));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
// 冻结所有的bean定义,说明注册的bean的定义将不被修改或者任何进一步的处理
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 初始化剩下的单实例(非惰性的)
beanFactory.preInstantiateSingletons();
}
总结一下:
- ConversionService的设置:之前我们提到过使用自定义类型转换器从String转换为Date的方式,那么,在Spring中还提供了另一种转换方式:使用Converter,具体例子就不再详述了
- 冻结配置:冻结所有的bean定义,说明注册的bean定义将不被修改或进行任何进一步的处理。
- 初始化非延迟加载:ApplicationContext 实现的默认行为就是在启动时将所有单例 bean 提前进行实例化。提前实例化意味着作为初始化过程的一部分,ApplicationContext实例会创建并配置所有的单例bean。通常情况下这是一件好事,因为这样在配置中的任何错误就会即刻被发现(否则的话可能要花几个小时甚至几天)。而这个实例化的过程就是在 finishBeanFactoryInitialization 中完成的。
finishRefresh()
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
1.initLifecycleProcessor
当ApplicationContext启动或停止时,它会通过LifecycleProcessor来与所有声明的bean的周期做状态更新,而在LifecycleProcessor的使用前首先需要初始化。
2.onRefresh
启动所有实现了Lifecycle接口的bean。
3.publishEvent
当完成ApplicationContext初始化的时候,要通过Spring中的事件发布机制来发出Context RefreshedEvent事件,以保证对应的监听器可以做进一步的逻辑处理。
至此,ApplicationContext启动代码分析结束,如果你能看到这,请给自己鼓个掌,感谢!