文章目录
- 前言
- 核心过程
- 1.ClassPathXmlApplicationContext
- 2.refresh()函数
- 1:)prepareRefresh-环境准备
- 2:)obtainFreshBeanFactory-初始化beanfactory,并加载xml文件读取
- 3:)prepareBeanFactory-容器功能扩展
- 4:)invokeBeanFactoryPostProcessors-激活bean的工厂处理器
- 5:)registerBeanPostProcessors-注册eanPostProcessor处理器
- 6:)initMessageSource-为上下文初始化Message源
- 7:)initApplicationEventMulticaster-初始化时间广播
- 8:)registerListeners-注册监听器
- 9:)finishRefresh-刷新容器
- 后语
前言
经过前面几章的分析,我们已经已经对Spring中的容器功能有了简单的了解,在前面的章 节中我们完整的了解了spring解析xml装载BeanDefination以及注册IOc容器初始化一个完整Bean的过程。然而这只是spring的冰山一角,对于java开发人员来说 ApplicationContext
已经烂熟于耳了,今天我们围绕它讲一讲容器的扩展功能。话不多说直接撸码!
早在第二节中已经介绍了spring加载XMl的几种方式,本次我们以 ClassPathXmlApplicationContext
作为切入点:
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("/application.xml");
核心过程
1.ClassPathXmlApplicationContext
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
在这个方法中设置路径是必不可少的步骤,ClassPathXmlApplicationContext
中可以将配置文件路径以数 组的方式传入,对数组进行解析并进行加载。而对于解析及功能实现都在refresh()中实现;还得往下看,这也是spring一贯的作风。
2.refresh()函数
进入refresh()
我们发现其实是进入了其父类中,先贴出主要代码如下:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing. 准备此上下文以进行刷新
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.告诉子类刷新内部bean工厂,初始化beanfactory,并加载xml文件读取。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.准备在这种情况下使用的bean工厂 对BeanFactory进行各种功能填充
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.允许在上下文子类中对bean工厂进行后处理。
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.调用在上下文中注册为bean的工厂处理器。
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.为此上下文初始化事件多播器。
initApplicationEventMulticaster();
// initialize other special beans in specific context subclasses.在特定上下文子类中初始化其他特殊bean。
onRefresh();
// Check for listener beans and register them.检查侦听器bean并注册它们
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.实例化所有剩余的(非延迟初始化)单例。
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.最后一步:完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发布相应的事件。
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("...");
}
destroyBeans();
cancelRefresh(ex);
throw ex;
} finally {
resetCommonCaches();
}
}
}
首先总结一下这个函数的作用:
- 初始化前的准备工作,例如对系统属性或者环境变量进行准备及验证。
在某种情况下项目的使用需要读取某些系统变量,而这个变量的设置很可能会影响着系统 的正确性,那么ClassPathXmlApplicationContext为我们提供的这个准备函数就显得非常必要, 它可以在Spring启动的时候提前对必需的变量进行存在性验证。 - 初始化BeanFactory,并进行XML文件读取。
之前有提到ClassPathXmlApplicationContext包含着BeanFactory所提供的_切特征,那么 在这一步骤中将会复用BeanFactory中的配置文件读取解析及其他功能,这一步之后,
ClassPathXmlApplicationcontext实际上就已经包含了 BeanFactory所提供的功能,也就是可以 进行bean的提取等基础操作了。 - 对BeanFactory进行各种功能填充。
©Qualifier与@Autowired应该是大家非常熟悉的注解,那么这两个注解正是在这一步骤中 增加的支持。 - 子类覆盖方法做额外的处理。
Spring之所以强大,为世人所推崇,除了它功能上为大家提供了便例外,还有一方面是它 的完美架构,开放式的架构让使用它的程序员很容易根据业务需要扩展已经存在的功能。这种 开放式的设计在Spring中随处可见,例如在本例中就提供了一个空的函数实现postProcess- BeanFactory来方便程序员在业务上做进一步扩展。 - 激活各种BeanFactory处理器。
- 注册拦截bean创建的bean处理器,这里只是注册,真正的调用是在getBean时候。
- 为上下文初始化Message源,即对不同语言的消息体进行国际化处理。
- 初始化应用消息广播器,并放入“applicationEventMulticaster" bean中。
- 留给子类来初始化其他的bean。
- 在所有注册的bean中查找listener bean,注册到消息广播器中。
- 1初始化剩下的单实例(非惰性的。
- 完成刷新过程,通知生命周期处理器liffecycleProcessor刷新过程,同时发出Context- RefreshEvent通知事件。
1:)prepareRefresh-环境准备
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
// 设置容器的状态
this.closed.set(false);
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment 空的 //留给子类覆盖
initPropertySources();
// 验证需要的属性文件是否都已经放入环境中
getEnvironment().validateRequiredProperties();
this.earlyApplicationEvents = new LinkedHashSet<>();
}
- initPropertySources函数是个空实现,这也正符合Spring的开放式结构设计,给用户最大扩展Spring的能力。 用户可以根据自身的需要重写initPropertySources方法,并在方法中进行个性化的属性处理及 设置。
- validateRequiredProperties则是对属性进行验证。
2:)obtainFreshBeanFactory-初始化beanfactory,并加载xml文件读取
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 初始化BeanFactory,并进行XML文件读取,并将得到的BeanFacotry记录在当前实体的属性中
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
obtainFreshBeanFactory 方法从字面理解是获取 BeanFactoryo。我们都知道,Application- Context是对BeanFactory的功能上的扩展,不但包含了 BeanFactory的全部功能更在其基础上 添加了大量的扩展应用,那么obtainFreshBeanFactory函数正是实现BeanFactory的地方,也就是经 过了这个函数后Applicationcontext就已经拥有了 BeanFactory的全部功能。我们还发现核心代码的实现又委托给了 refreshBeanFactory
函数;
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 创建 BeanFactory XmlBeanFactory就是DefaultListableBeanFactory的子类,提供了 XmlBeanDefinitionReader 类型的 reader 属性,也就是说 DefaultListableBean-Factory是容器的基础。必须首先要实例化
DefaultListableBeanFactory beanFactory = createBeanFactory();
// 为了序列化指定id,如果需要的话,让这个BeanFactory从id反序列化到BeanFactory对象
beanFactory.setSerializationId(getId());
// 定制beanFactory,设置相关属性,包括是否允许覆盖同名称的不同定义的对象以及循环依赖
customizeBeanFactory(beanFactory);
// 加载 BeanDefinitiono
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("...”);
}
}
这个函数是非常重要的,在此重点讲一下:
- 创建 DefaultListableBeanFactory0
不知道大家是否还有映像在第二节开篇的时候,BeanFactory bf = new XmlBeanFactory(“application.xm”),这一句代码;其中的 XmlBeanFactory 继承自 DefaultListableBeanFactory ,并提供了 XmlBeanDefinitionReader 类型的 reader 属性,也就是说 DefaultListableBean-Factory是容器的基础。必须首先要实例化,那么在这里就是实例化DefaultListableBeanFactory 的步骤。 - 指定序列化ID。
- 定制 BeanFactory。
- 加载 BeanDefinition,没错这一步正是我们整个
第二节
所讲的类容。 - 使用全局变量记录BeanFactory类实例。
因为DefkultListableBeanFactory类型的变量beanFactory是函数内的局部变量,所以要使用 全局变量记录解析结果。
3:)prepareBeanFactory-容器功能扩展
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.
// 添加默认的系统环境bean
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());
}
}
流式的处理流程为容器扩展功能属性,这也是spring如此强大的原因,正是由这些组件的支持。
- 增加对SpEL语言的支持,比如#{xxx.xxx}这样的表达式。
- 增加对属性编辑器的支持。
- 增加对一些内置类,比如EnvironmentAware、MessageSourceAware的信息注入。
- 设置了依赖功能可忽略的接口。
- 注册一些固定依赖的属性。
- 增加Aspect!的支持。
将相关环境变量及属性注册以单例模式注册。
在此我们重点讲一下 ApplicationContextAwareProcessor
处理器,在上述代码中有这样一句
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
其实主要目的就是注册个BneaPostProcessor。ApplicationContextAwareProcessor 实现 BeanPostProcessor 接口,在第三节的内容中,在bean实例化的时候,也就是Spring激活bean的init-method
的前后,会调用BeanPostProcessor 的 postProcessBefbrelnitialization 方法和 postProcessAfterlnitialization 方法。同样,对 于ApplicationContextAwareProcessor我们也关心这两个方法。我们发现 postProcessBefbrelnitialization
方法中又调用了 invokeAwareInterfeces
;我们或许已经或多或少了解了 Spring的用意,实现这些Aware接口的bean在被初始 化之后,可以取得一些对应的资源。
4:)invokeBeanFactoryPostProcessors-激活bean的工厂处理器
上述类容以及第三节的部分我们已经说了BeanPostProcessor 接口;在此我们先了解下BeanFactoryPostProcessor的用法。BeanFactoryPostProcessor 接口跟 BeanPostProcessor 类似,可以对 bean 的定义(配置元数 据)进行处理。也就是说,Spring IoC容器允许BeanFactoryPostProcessor在容器实际实例化任 何其他的bean之前读取配置元数据,并有可能修改它。如果你愿意,你可以配置多个 BeanFactoryPostProcessor0你还能通过设置“order”属性来控制 BeanFactoryPostProcessor 的执行次序。简言之就是BeanFactoryPostProcessor接口能在容器实例化bean之前让你修改bean的一些属性。
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
// 对 BeanDefinitionRegistry 类型的处理
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<>();
// 硬编码注册的后处理器
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
// BeanDefinitionRegistryPostProcessor 在 BeanFactoryPostProcessor 的基础上还有自己定义的方法,需要先调用
registryProcessor.postProcessBeanDefinitionRegistry(registry);
//记录常规 BeanFactoryPostProcessor
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
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();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
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);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
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();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 常规的BeanFactoryPostProcessors
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// 对于配置中读取的BeanFactoryPostProcessor的处理
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 对后处理器进行分类
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
} else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
// 排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 按照 order进行排序
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
// 无序的直接调用
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
beanFactory.clearMetadataCache();
}
从上面的方法中我们看到,对于BeanFactoryPostProcessor的处理主要分两种情况进行,一个 是对于BeanDefinitionRegistry类的特殊处理,另一种是对普通的BeanFactoryPostProcessor进行处 理。而对于每种情况都需要考虑硬编码注入注册的后处理器以及通过配置注入的后处理器。
对于BeanDefinitionRegistry类型的处理类的处理主要包括以下内容。
-
对于硬编码注册的后处理器的处理,主要是通过AbstractApplicationContext中的添加处 理器方法 addBeanFactoryPostProcessor 进行添加。
public void addBeanFactoryPostProcessor( BeanFactoryPostProcessor beanFactoryPostProcessor) { this ・ beanFactoryPostProcessors.add(beanFactoryPostProcessor); }
添加后的后处理器会存放在beanFactoiyPostProcessors中,而在处理
BeanFactoryPostProcessor 时候会首先检测 beanFactoryPostProcessors 是否有数据。当然,BeanDefinitionRegistryPostProcessor 继承自BeanFactoryPostProcessor,不但有BeanFactoryPostProcessor的特性,同时还有自己定义 的个性化方法,也需要在此调用。所以,这里需要从beanFactoryPostProcessors中挑出 BeanDefinitionRegistryPostProcessor 的后处理器,并进行其 postProcessBeanDefinitionRegistry 方 法的激活。
添加后的后处理器会存放在beanFactoiyPostProcessors中,而在处理BeanFactoryPostProcessor 时候会首先检测 beanFactoryPostProcessors 是否有数据。当然,BeanDefinitionRegistryPostProcessor 继承自BeanFactoryPostProcessor,不但有BeanFactoryPostProcessor的特性,同时还有自己定义 的个性化方法,也需要在此调用。所以,这里需要从beanFactoryPostProcessors中挑出 BeanDefinitionRegistryPostProcessor 的后处理器,并进行其 postProcessBeanDefinitionRegistry 方 法的激活。
-
记录后处理器主要使用了 3个List完成。
- registryPostProcessors:记录通过硬编码方式注册的 BeanDefinitionRegistryPostProcessor 类型的处理器。
- regularPostProcessors:记录通过硬编码方式注册的BeanFactoryPostProcessor类型的处 理器。
- registryPostProcessorBeans:记录通过配置方式注册的 BeanDefinitionRegistryPostProcessor 类型的处理器。
-
对以上所记录的List中的后处理器进行统一调用BeanFactoryPostProcessor的 postProcessBeanFactory 方法。
-
对 beanFactoryPostProcessors 中非 BeanDefinitionRegistryPostProcessor 类型的后处理器进行 统一的 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法调用。
-
普通 beanFactory 处理。
BeanDefinitionRegistryPostProcessor 只对 BeanDefinitionRegistry 类型的 ConfigurableListable- BeanFactory有效,所以如果判断所示的beanFactory并不是BeanDefinitionRegistry,那么便可 以忽略 BeanDefinitionRegistryPostProcessor,而直接处理 BeanFactoryPostProcessor,当然获取 的方式与上面的获取类似。这里需要提到的是,对于硬编码方式手动添加的后处理器是不需要做任何排序的,但是在 配置文件中读取的处理器,Sping并不保证读取的顺序。所以,为了保证用户的调用顺序的要求,Spring对于后处理器的调用支持按照PriorityOrdered或者Ordered的顺序调用。
5:)registerBeanPostProcessors-注册eanPostProcessor处理器
首先强调一点这里只是注册并不是调用,具体是在getBean()
的时候调用,这一点我们在第三节也说到了;下面我们继续看代码:
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
/*
* BeanPostProcessorChecker•是一个普通的信息打印,可能会有些情况,
•当Spring的配置中的后处理器还没有被注册就已经开始了 bean的初始化时
*便会打印出BeanPostProcessorChecker中设定的信息
*/
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 使用PriorityOrdered保证顺序
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 存储 MergedBeanDefinitionPostProcessor
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
// 使用Ordered保证顺序
List<String> orderedPostProcessorNames = new ArrayList<>();
// 无序的
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
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);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.首先,注册实现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. 最后,重新注册所有内部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 的处理,不但要实现注册功能,而且还要实现对后处理器的激活操作,所以需要载入配置中的定义并激活;而对于BeanPostProcessor并不需要马上调用,再说,硬编码的方式实现的功能是将后处理器提取并调用,这里并不需要调用,当然不需要考虑硬编码的方式了,这里的 功能只需要将配置文件的BeanPostProcessor提取出来并注册进入beanFactory就可以了。
6:)initMessageSource-为上下文初始化Message源
不做过多说明,根据字眼我们就能发现他是初始化不同语言的消息体,即国际化处理相关的扩展。
7:)initApplicationEventMulticaster-初始化时间广播
没错通过关键字我们就能知道这个方法是容器扩展监听事件的实现。
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 + "]");
}
}
}
通过代码我们发现,该方法就是两种情况:
- 如果用户自定义了事件广播器,那么使用用户自定义的事件广播器。
- 如果用户没有自定义事件广播器,那么使用默认的ApplicationEventMulticaster().
在默认的广播事件处理器 SimpleApplicationEventMulticaster
中我们发现了一段很有价值的代码:
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
} else {
invokeListener(listener, event);
}
}
}
很明显了,当产生Spring事件的时候会默认使用SimpleApplicationEventMulticaster的 multicastEvent来广播事件,遍历所有监听器,并使用监听器中的onApplicationEvent方法来进 行监听器的处理。而对于每个监听器来说其实都可以获取到产生的事件,但是是否进行处理则 由事件监听器来决定。
8:)registerListeners-注册监听器
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);
}
}
}
spring的监听、事件处理是很好用也很使用的功能,上述代码很好理解获取所有的监听器以及所有的事件,统一交给第七步中所配置的处理器处理。
9:)finishBeanFactoryInitialization-初始化所有非延迟加载的bean
我们都知道spring的bean有懒加载(@lazy)与立即加载的区别,在此就是初始化非延迟加载的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.停止使用临时的ClassLoader进行类型匹配。
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.允许缓存所有bean定义元数据,而不期望进一步的更改。
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons. 初始化非延迟的单利的bean
/**
* Applicationcontext实现的默认行为就是在启动时将所有单例bean提前进行实例化。提 前实例化意味着作为初始化过程的一部分,
* Applicationcontext实例会创建并配置所有的单例 bean通常情况下这是一件好事,因为这样在配置中的任何错误就会即刻被发现
*/
beanFactory.preInstantiateSingletons();
}
在此我们重点关注一下 beanFactory.preInstantiateSingletons()
这个函数,进入这个这个函数:
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
// 获取之前注册的 beanDefinition对象
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
// 装配 RootBeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 判断是否是 factoryBean
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
} else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
} else {
// 初始化 bean 也就是将 beanDefinition -》 完整bean的过程
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...触发所有适用bean的初始化后回调...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
是不是有一种很亲切的感觉?特别是 getBean(beanName)
函数?到这里再次与之前的第三节内容对应起来了,又到了初始化bean的环节,在此不做阐述。
9:)finishRefresh-刷新容器
至此整个容器的扩展功能已经完毕了,在此更新容器状态,发布最终的容器启动完成事件。
后语
不积跬步,无以至千里 ,不积小流 ,无以成江海。撸起袖子加油干!