热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于AnnotationConfigApplicationContext的容器创建过程(SpringVersion5.2.0)

首先你要引入依赖org.springframeworkspring-context

首先你要引入依赖


<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.0.RELEASEversion>
dependency>

然后你得有个配置类


import org.springframework.context.annotation.Configuration;
@Configuration
public class SimpleConfig {
}

最后是启动程序


public static void main(String[] args){
AnnotationConfigApplicationContext context
= new AnnotationConfigApplicationContext(SimpleConfig.class);
}


开始

进入构造方法


public AnnotationConfigApplicationContext(Class... componentClasses) {
this();
this.register(componentClasses);
this.refresh();
}

这种情况分为三步:


1. 调用重载构造方法,目的是初始化bean定义扫描器。



public AnnotationConfigApplicationContext() {
// 这是{ClassPathBeanDefinitionScanner}的另一种选择,它应用了相同的注释解析,但是只针对显式注册的类。
this.reader = new AnnotatedBeanDefinitionReader(this);
// 一个bean定义扫描器,它检测类路径上的候选bean,在给定的注册中心注册相应的bean定义({BeanFactory}或{ApplicationContext})。
this.scanner = new ClassPathBeanDefinitionScanner(this);
}


2. 注册给定的配置类



public void register(Class... componentClasses) {
Assert.notEmpty(componentClasses,
"At least one component class must be specified");
// 实际上调用AnnotatedBeanDefinitionReader#doRegisterBean,注册给定的bean
this.reader.register(componentClasses);
}


3. 刷新。



// 实际上调用的父类刷新方法
org.springframework.context.support.AbstractApplicationContext#refresh


refresh方法

先看下整个流程


public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1. 为上下文刷新做准备:设置其启动开始时间和活动标志以及执行任何属性源的初始化。初始化earlyApplicationListeners和earlyApplicationEvents。
prepareRefresh();
// 2. 告诉子类刷新内部bean工厂。返回这个上下文所持有的内部BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// ☆☆☆3. 准备bean工厂以供在此上下文中使用。配置工厂的标准上下文特征,比如上下文的类加载器、后置处理器。
prepareBeanFactory(beanFactory);
try {
// 4. 由上下文子类实现的方法,对bean工厂的后置处理
// 这个时候所有bean定义都已加载,但还没有实例化bean。这允许在特定的ApplicationContext实现中注册特殊的BeanPostProcessors
postProcessBeanFactory(beanFactory);
// ☆☆☆5. 调用上下文中注册为bean的工厂处理器。
// 实例化并调用所有已注册的BeanFactoryPostProcessor bean,必须在单例(singleton)实例化之前调用。
// 实际上是由工具类PostProcessorRegistrationDelegate负责调用执行的。
// ***BeanFactoryPostProcessor,是针对整个工厂生产出来的BeanDefinition作出修改或者注册。作用于BeanDefinition时期。
invokeBeanFactoryPostProcessors(beanFactory);
// ☆☆☆6. 注册拦截bean创建的bean处理器。
// 实例化并注册所有BeanPostProcessor bean,如果给定,则遵循显式顺序。必须在任何应用程序bean的实例化之前调用。
// 实际上是由工具类PostProcessorRegistrationDelegate负责调用执行的。
// ***BeanPostProcessor 在bean实例化、初始化前后执行
registerBeanPostProcessors(beanFactory);
// 7. 为上下文初始化消息源。
// MessageSource干嘛用的:比如国际化
initMessageSource();
// ☆☆☆8. 为上下文初始化事件广播程序。初始化ApplicationEventMulticaster。如果上下文中没有定义,则使用SimpleApplicationEventMulticaster。
initApplicationEventMulticaster();
// 9. 由上下文的子类实现的方法,初始化其它特殊Bean
// 模板方法,可以覆盖该方法以添加特定于上下文的刷新工作。在单例(singleton)实例化之前,在初始化特殊bean时调用。
onRefresh();
// ☆☆☆10. 检查监听器bean并注册它们。
// 添加的是ApplicationListener的实现类。发布事件的是ApplicationEventMulticaster,接收事件的是ApplicationListener。
registerListeners();
// ☆☆☆11. 实例化所有剩余的(非懒加载)单例。
finishBeanFactoryInitialization(beanFactory);
// ☆☆☆12. 最后一步:发布相应的事件。
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn(
"Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// ☆☆☆13. 销毁已经创建的单例,以避免挂起资源。
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();
}
}
}

流程总结:


1. 为上下文刷新做准备:设置其启动开始时间和活动标志以及执行任何属性源的初始化。初始化earlyApplicationListeners和earlyApplicationEvents。

2. 告诉子类刷新内部bean工厂。返回这个上下文所持有的内部BeanFactory。

3. 准备bean工厂以供在此上下文中使用。配置工厂的标准上下文特征,比如上下文的类加载器、后置处理器。

4. 由上下文子类实现的方法,对bean工厂的后置处理。

5. 调用上下文中注册为bean的工厂处理器(BeanFactoryPostProcessor)。

6. 注册拦截bean创建的bean处理器。(BeanPostProcessor)

7. 为上下文初始化消息源。

8. 为上下文初始化事件广播程序。初始化ApplicationEventMulticaster。如果上下文中没有定义,则使用SimpleApplicationEventMulticaster。

9. 由上下文的子类实现的方法,初始化其它特殊Bean。

10. 检查监听器bean并注册它们。和第8步协作。

11. 实例化所有剩余的(非懒加载)单例。

12. 最后一步:发布相应的事件。

如果发生异常----->

13. 销毁已经创建的单例,以避免挂起资源。



下面步骤拆分


0. 刷新过程有几个地方是由子类实现的,这里先做个例子


import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* Created by 小LUA on 2020-02-24 10:27.
*/
public class MyApp extends AnnotationConfigApplicationContext {
public MyApp(Class... componentClasses) {
super(componentClasses);
}
@Override
protected void initPropertySources() {
super.initPropertySources();
System.out.println(
"子类实现,初始化其它属性源...");
}
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.postProcessBeanFactory(beanFactory);
System.out.println(
"子类实现对bean工厂的后置处理...");
}
@Override
protected void onRefresh() throws BeansException {
super.onRefresh();
System.out.println(
"子类实现初始化其他特殊Bean...");
}
public static void main(String[] args){
ApplicationContext context
= new MyApp(SimpleConfig.class);
// ApplicationContext cOntext= new AnnotationConfigApplicationContext(SimpleConfig.class);
}
}

输出

技术分享图片


1. 为上下文刷新做准备


protected void prepareRefresh() {
// 启动开始时间
this.startupDate = System.currentTimeMillis();
// 设置活动开关
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace(
"Refreshing " + this);
}
else {
logger.debug(
"Refreshing " + getDisplayName());
}
}
// 在上下文环境中初始化任何占位符属性源。这里是由子类实现的。
initPropertySources();
// 验证所有标记为需要的属性都是可解析的
getEnvironment().validateRequiredProperties();
// 存储预刷新的 ApplicationListeners
if (this.earlyApplicatiOnListeners== null) {
this.earlyApplicatiOnListeners= new LinkedHashSet<>(this.applicationListeners);
}
else {
// 将本地应用程序监听器重置为预刷新状态。
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// 初始化早期事件容器。收集早期的应用程序事件,一旦广播者 multicaster 可用,这里存储的事件将被发布
this.earlyApplicatiOnEvents= new LinkedHashSet<>();
}

这里可以理解为:飞机起飞之前肯定要先启动(prepareRefresh),这个时候肯定要先看一下基础功能是否正常。


> 启动时间

> 系统状态更新为已激活

> 执行附加的操作(子类实现

> 事件广播者和收听者准备就绪



2. 告诉子类刷新内部bean工厂。返回这个上下文所持有的内部BeanFactory。


protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 设置refreshed标志位为true
refreshBeanFactory();
// 返回内部BeanFactory
return getBeanFactory();
}
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call ‘refresh‘ once");
}
this.beanFactory.setSerializationId(getId());
}
public final ConfigurableListableBeanFactory getBeanFactory() {
return this.beanFactory;
}

这一步只做了两件事,可以理解为:飞机已经决定起飞(refreshed)了


> 设置refreshed标志位为true

> 返回内部BeanFactory



3. ☆☆☆准备bean工厂以供在此上下文中使用。配置工厂的标准上下文特征,比如上下文的类加载器、后置处理器等


protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 告诉内部BeanFactory使用上下文的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
// 设置Bean表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(
new ResourceEditorRegistrar(this, getEnvironment()));
// 配置上下文回调
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接口不被注册为可解析的类型
// 消息源注册为Bean
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.
class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.
class, this);
beanFactory.registerResolvableDependency(ApplicationContext.
class, this);
// 将用于检测内部bean的早期后处理器注册为Applicationlistener。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
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()));
}
// 注册默认的环境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());
}
}

这一步初始化了BeanFactory必须的一些工具。可以理解为:控制飞机的正常运行,需要多个子系统的协作,这里加载必须的子系统。


> 配置类加载器

> 配置后置处理器

> ...



4. 由上下文子类实现的方法,对bean工厂的后置处理


这个时候所有bean定义都已加载,但还没有实例化bean。这允许在特定的ApplicationContext实现中注册特殊的BeanPostProcessors


这一步的体现见上面第0步


5.☆☆☆调用上下文中注册为bean的工厂后置处理器。


// 允许自定义修改应用程序上下文的bean定义,调整上下文的底层bean工厂的bean属性值。
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List
beanFactoryPostProcessors) {
// 先执行 BeanDefinitionRegistryPostProcessors
Set processedBeans = new HashSet<>();
// 如果是BeanDefinitionRegistry接口的实现
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry
= (BeanDefinitionRegistry) beanFactory;
List
regularPostProcessors = new ArrayList<>();
List
registryProcessors = new ArrayList<>();
// 遍历执行Bean定义注册的后置处理器
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor
=
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// 第一:不要在这里初始化FactoryBean:我们需要保证所有常规bean未初始化,以便让bean factory后置处理器应用于它们!
// 第二:将实现PriorityOrdered, Ordered和其他操作的BeanDefinitionRegistryPostProcessors分开。
List currentRegistryProcessors = new ArrayList<>();
// 先执行实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessors
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();
// 然后执行实现Ordered接口的BeanDefinitionRegistryPostProcessors
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();
// 最后执行所有剩下的BeanDefinitionRegistryPostProcessors
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();
}
// 最最后,调用到目前为止处理的所有处理器的postProcessBeanFactory回调。
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// 不是BeanDefinitionRegistry接口的实现,执行用上下文实例注册的工厂处理器(这个方法就是一个遍历执行的过程)
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 不要在这里初始化FactoryBean:我们需要保证所有常规bean未初始化,以便让bean factory后置处理器应用于它们!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.
class, true, false);
// 将实现PriorityOrdered, Ordered和其他操作的BeanFactoryPostProcessors分开。
List priorityOrderedPostProcessors = new ArrayList<>();
List
orderedPostProcessorNames = new ArrayList<>();
List
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);
}
}
// 先执行实现PriorityOrdered接口的BeanFactoryPostProcessors
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 然后执行实现Ordered接口的BeanFactoryPostProcessors
List orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.
class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 最后执行所有剩下的BeanFactoryPostProcessors
List nOnOrderedPostProcessors= new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.
class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// 清除缓存的合并bean定义,因为后处理器可能修改了原始的元数据
beanFactory.clearMetadataCache();
}

看起来很多,但是主要分为两部分,而这两部分的逻辑是一样的。


⑴ 首先把后置处理器分为BeanDefinitionRegistryPostProcessor(BeanDefinitionRegistry后置处理器)和BeanFactoryPostProcessor(BeanFactory后置处理器)。

  ①将实现PriorityOrdered, Ordered和其他操作的后置处理器分开。

  ②先执行实现PriorityOrdered接口的XXXPostProcessor

  ③然后执行实现Ordered接口的XXXPostProcessor

  ④最后执行所有剩下的XXXPostProcessor

⑵ 清除缓存的合并bean定义,因为后处理器可能修改了原始的元数据



6. ☆☆☆注册拦截bean创建的bean处理器。


public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames
= beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 注册BeanPostProcessorChecker,它在BeanPostProcessor实例化期间创建bean时记录日志
// 例如,当一个bean不能被所有的BeanPostProcessor处理时。
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(
new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 将实现PriorityOrdered, Ordered和其他操作的BeanPostProcessors分开。
List priorityOrderedPostProcessors = new ArrayList<>();
List
internalPostProcessors = new ArrayList<>();
List
orderedPostProcessorNames = new ArrayList<>();
List
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);
}
}
// 先注册实现PriorityOrdered接口的BeanPostProcessors
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 然后注册实现Ordered接口的BeanPostProcessors
List orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
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);
// 最后注册所有剩下的BeanPostProcessors.
List nOnOrderedPostProcessors= new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp
= beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 最后,重新注册所有的内部BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 将后处理器重新注册为ApplicationListener用于检测内部bean,将其移动到处理链的末端(用于获取代理等)。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

这部分的套路和执行BeanFactory后置处理器的过程是一样的。


⑴ 注册Bean后置处理器

  ① 将实现PriorityOrdered, Ordered和其他操作的BeanPostProcessors分开。

  ②先注册实现PriorityOrdered接口的BeanPostProcessors

  ③然后注册实现Ordered接口的BeanPostProcessors

  ④最后注册所有剩下的BeanPostProcessors.

⑵重新注册所有的内部BeanPostProcessors.

⑶将后处理器重新注册为ApplicationListener用于检测内部bean,将其移动到处理链的末端(用于获取代理等)。



7. 为上下文初始化消息源。


protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory
= getBeanFactory();
// 如果本地存在messageSource的Bean
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.isTraceEnabled()) {
logger.trace(
"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.isTraceEnabled()) {
logger.trace(
"No ‘" + MESSAGE_SOURCE_BEAN_NAME + "‘ bean, using [" + this.messageSource + "]");
}
}
}


8. ☆☆☆为上下文初始化事件广播程序。初始化ApplicationEventMulticaster。如果上下文中没有定义,则使用SimpleApplicationEventMulticaster。


protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory
= getBeanFactory();
// 如果本地存在applicationEventMulticaster的Bean
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
// 给applicationEventMulticaster属性赋值
this.applicatiOnEventMulticaster=
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.
class);
if (logger.isTraceEnabled()) {
logger.trace(
"Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
// 否则初始化一个SimpleApplicationEventMulticaster,然后注册即可
this.applicatiOnEventMulticaster= new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace(
"No ‘" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "‘ bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}

这部分就是初始化了一个事件广播者


9. 由上下文的子类实现的方法,初始化其它特殊Bean


模板方法,可以覆盖该方法以添加特定于上下文的刷新工作。在单例(singleton)实例化之前,在初始化特殊bean时调用。


这一步的体现见上面第0步


10. ☆☆☆检查监听器bean并注册它们。


protected void registerListeners() {
// 首先注册静态指定的监听器。
for (ApplicationListener listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 不要在这里初始化factorybean:我们需要保证所有常规bean未初始化,以便让后处理器应用于它们!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 发布早期的应用事件,到此为止我们已经有了一个广播者
Set earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicatiOnEvents= null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}

这里完成了两个事情:


> 注册应用程序监听器

> 发布早期事件(观察者模式的经典体现)



11. ☆☆☆实例化所有剩余的(非懒加载)单例。


 完成上下文bean工厂的初始化,初始化所有剩余的单例bean。



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后置处理器
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal
-> getEnvironment().resolvePlaceholders(strVal));
}
// 尽早初始化LoadTimeWeaverAware bean,以便尽早注册它们的转换器。
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用临时类加载器进行类型匹配。
beanFactory.setTempClassLoader(null);
// 允许缓存所有的bean定义元数据,不期望有进一步的更改。
beanFactory.freezeConfiguration();
// 实例化所有剩余的(非懒加载)单例。
beanFactory.preInstantiateSingletons();
}

这一步干的工作比较多:


> 为上下文初始化转换服务

> 注册一个默认的嵌入式值解析器(主要用于解析注释属性值)

> 停止使用临时类加载器进行类型匹配。

> 允许缓存所有的bean定义元数据,不期望有进一步的更改。

> 实例化所有剩余的(非懒加载)单例。


关于preInstantiateSingletons的执行过程,实际上就是getBean的过程了,这部分上一篇文章做了解读。


12. ☆☆☆最后一步:发布相应的事件。


protected void finishRefresh() {
// 清除上下文级别的资源缓存(比如扫描的ASM元数据)。
clearResourceCaches();
// 为此上下文初始化生命周期处理器。
initLifecycleProcessor();
// 将生命周期处理器的running标志位设置为true
getLifecycleProcessor().onRefresh();
// 发布最终事件。
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
// 看一下ContextRefreshedEvent
public void publishEvent(ApplicationEvent event) {
publishEvent(event,
null);
}
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event,
"Event must not be null");
// Decorate event as an ApplicationEvent if necessary
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent
= (ApplicationEvent) event;
}
else {
applicationEvent
= new PayloadApplicationEvent<>(this, event);
if (eventType == null) {
eventType
= ((PayloadApplicationEvent) applicationEvent).getResolvableType();
}
}
// 如果可能的话,现在就广播;或者等广播可用的时候立即广播。
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
// 获取事件广播者,异步广播事件给对应的Listener
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// 通过父上下文发布事件
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext)
this.parent).publishEvent(event, eventType);
}
else {
this.parent.publishEvent(event);
}
}
}

它是怎么广播给监听者的呢?


public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type
= (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor
= getTaskExecutor();
// 遍历应用程序监听器
for (ApplicationListener listener : getApplicationListeners(event, type)) {
// 如果指定了executor,就走异步处理
if (executor != null) {
executor.execute(()
-> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
protected void invokeListener(ApplicationListener listener, ApplicationEvent event) {
ErrorHandler errorHandler
= getErrorHandler();
if (errorHandler != null) {
try {
// 执行Listener,准确来说是监听器的【收听】方法
doInvokeListener(listener, event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
doInvokeListener(listener, event);
}
}
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
// 这里调用ApplicationListener接口唯一的方法,也就是说,当接收到了事件,监听器要如何做的方法
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
String msg
= ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let‘s suppress the exception and just log a debug message.
Log logger = LogFactory.getLog(getClass());
if (logger.isTraceEnabled()) {
logger.trace(
"Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}

这里仅仅扩展一下,看下Spring如何利用【观察者模式】的。

----------------------------------------

这一步显而易见,善后处理:


> 清除上下文级别的资源缓存

> 为此上下文初始化生命周期处理器

> 发布最终事件(上下文已刷新事件)



13. ☆☆☆销毁已经创建的单例,以避免挂起资源。(异常情况)


// 如果你看了我上一篇文章,你会知道这段代码以及逻辑在哪里。这里不再赘述
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}


总结


以前我觉得Spring源码是个深奥的东西,因为看不懂,就不想去研究。后来逼着自己看了N遍,你会觉得,也就那吊样吧(学习人家的代码习惯,已经如何把设计模式合理应用的)


 


推荐阅读
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • CentOS 6.5安装VMware Tools及共享文件夹显示问题解决方法
    本文介绍了在CentOS 6.5上安装VMware Tools及解决共享文件夹显示问题的方法。包括清空CD/DVD使用的ISO镜像文件、创建挂载目录、改变光驱设备的读写权限等步骤。最后给出了拷贝解压VMware Tools的操作。 ... [详细]
  • java ssm框架_Java SSM框架的简单搭建
    1.添加依赖包,可以通过properties统一框架版本UTF-81.71.75.0.8.RELEASEjunitjunit4.11testjavax.servlet ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 本文介绍了如何清除Eclipse中SVN用户的设置。首先需要查看使用的SVN接口,然后根据接口类型找到相应的目录并删除相关文件。最后使用SVN更新或提交来应用更改。 ... [详细]
author-avatar
手机用户2502907451
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有