一、概述

1.Spring Context概念

创建上下文并将BeanPostProcessor加载到spring

2.Spring Application Context概念

Spring通过应用上下文(Application Context)装载bean的定义并把它们组装起来。Spring应用上下文全权负责对象的创建和组装。

3. 关系

(1)Spring Context 模块核心是Spring Context

(2)Spring Context 核心是Spring Application Context

(3)Spring Application Context 的核心方法是 AbstractApplicationContext

二、AbstractApplicationContext之刷新源码分析

1. 基础源码

高效记忆:Spring应用文刷新 --- 刷机

(1)手机系统太卡了于是自己刷机。首先 准备刷机环境 (准备刷新上下文环境),准备好后老系统 初始化并加载 定义信息(初始化BeanFactory,并加载bean definitions信息)

(2)然后进行系统 配置 并(对beanFacotry进行配置)开始系统 激活 并提交过程(激活BeanFactoryPostProcessors)

(3)再进行验证码 注册 并提交过程(注册BeanPostProcessors),注册后新系统 初始化信息资源、广播 且注册监听器(初始化MessageSource、初始化事件广播器、注册事件监听器)

(4)最后系统 热加载弹粒 并(构造热加载单例bean)完成刷机 (完成刷新过程,通知生命周期处理器),如果刷机 错误销户并修改 激活标识(销毁bean、修改active标识)

	@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh(); // #1 准备刷新上下文环境 // Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // #2 初始化BeanFactory,并加载bean definitions信息 // Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory); // #3 对beanFacotry进行配置 try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory); // #4 提供给子类扩展的预留方法 // Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory); // #5 激活BeanFactoryPostProcessors // Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory); // #6 注册BeanPostProcessors // Initialize message source for this context.
initMessageSource(); // #7 初始化MessageSource // Initialize event multicaster for this context.
initApplicationEventMulticaster(); // #8 初始化事件广播器 // Initialize other special beans in specific context subclasses.
onRefresh(); // #9 提供给子类初始化其他的Bean // Check for listener beans and register them.
registerListeners(); // #10 注册事件监听器 // Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory); // #11 构造热加载单例bean // Last step: publish corresponding event.
finishRefresh(); // #12 完成刷新过程,通知生命周期处理器
} 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(); // #13 出错了,销毁bean // Reset 'active' flag.
cancelRefresh(ex); // #14 出错了,修改active标识 // 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();
}
}
}

2.初始化并加载 obtainFreshBeanFactory

AbstractApplicationContext---obtainFreshBeanFactory ----> AbstractRefreshableApplicationContext---refreshBeanFactory

protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) { // #1 如果已存在BeanFactory,销毁原来的BeanFactory
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory(); // #2 创建DefaultListableBeanFactory
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
// #3 加载bean definitions信息,loadBeanDefinitions是抽象方法,不同实现类会从不同的配置中获取bean definitions信息,
// 如AnnotationConfigWebApplicationContext,XmlWebApplicationContext。
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}

3.激活 BeanFactoryPostProcessors

(1)BeanFactoryPostProcessor是spring提供的扩展接口,可以通过BeanFactoryPostProcessor对beanFactory进行自定义处理,如修改其他BeanDefinition的配置。

(2)BeanFactoryPostProcessor可以调整beanFactory,甚至修改BeanDefinition,如CustomEditorConfigurer,将用户定义的PropertyEditor注册到beanFactory中,以便后续使用。

(3)BeanDefinitionRegistryPostProcessor可以注册新的BeanDefinition,如ConfigurationClassPostProcessor,是实现springboot很关键的类

AbstractApplicationContext---invokeBeanFactoryPostProcessors ----> PostProcessorRegistrationDelegate---invokeBeanFactoryPostProcessors

public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { Set<String> processedBeans = new HashSet<String>();
// #1 如果beanFactory是BeanDefinitionRegistry,需要处理BeanFactoryPostProcessors,
// BeanDefinitionRegistryPostProcessor,否则只处理BeanFactoryPostProcessors
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
new LinkedList<BeanDefinitionRegistryPostProcessor>();
// #2 方法参数beanFactoryPostProcessors是AbstractApplicationContext---beanFactoryPostProcessors属性,
// 用户可以通过AbstractApplicationContext---addBeanFactoryPostProcessor方法添加BeanFactoryPostProcessor。这里对beanFactoryPostProcessors参数进行分类
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryPostProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
registryPostProcessors.add(registryPostProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
} // #3 获取beanFactory已经存在的BeanDefinitionRegistryPostProcessor,这里并没有直接构建BeanDefinitionRegistryPostProcessor,而且通过beanName获取
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// #4 获取实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,添加到priorityOrderedPostProcessors
processedBeans.add(ppName);
}
}
// #5 对priorityOrderedPostProcessors排序
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
// #6 排序结果添加到registryPostProcessors
registryPostProcessors.addAll(priorityOrderedPostProcessors);
// #7 调用BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry); // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
for (String ppName : postProcessorNames) {
// #8 处理实现了Ordered的BeanDefinitionRegistryPostProcessor
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(beanFactory, orderedPostProcessors);
registryPostProcessors.addAll(orderedPostProcessors);
invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry); // 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) {
// #9 处理剩余的BeanDefinitionRegistryPostProcessor
if (!processedBeans.contains(ppName)) {
BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
registryPostProcessors.add(pp);
processedBeans.add(ppName);
pp.postProcessBeanDefinitionRegistry(registry);
reiterate = true;
}
}
} // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} ...
}

4.初始化事件广播 initApplicationEventMulticaster

4.1 Spring事件体系包括三个组件:

ApplicationEvent事件,ApplicationListener事件监听器,ApplicationEventMulticaster事件广播器。

4.2 事件广播器负责管理事件监听器,并将事件广播给监听器。

AbstractApplicationContext --- initApplicationEventMulticaster

rotected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); //#1 使用用户定义的事件广播器
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); //#2 使用默认的事件广播器
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}

4.3 spring事件

(1)spring提供了context start,stop,close,refresh等事件,ApplicationListener --- onApplicationEvent负责处理spring中的事件。

(2)我们可以通过实现ApplicationListener接口自行处理事件,也可以通过PublishListener自定义事件监听器。

使用默认的事件广播器 AbstractApplicationContexton --- publishEvent ----> SimpleApplicationEventMulticaster --- multicastEvent

public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor(); // #1 如果配置了Executor,使用Executor多线程处理
if (executor != null) {
executor.execute(new Runnable() {
public void run() {
invokeListener(listener, event);
}
});
}
else {
invokeListener(listener, event); // #2 否则单线程处理
}
}
}

5.注册事件监听器

AbstractApplicationContext --- registerListeners将初始化事件监听器ApplicationListener,并绑定到事件广播器上。

protected void registerListeners() {
for (ApplicationListener<?> listener : getApplicationListeners()) { // #1 getApplicationListeners()获取的是AbstractApplicationContext --- applicationListeners,用户可以通过AbstractApplicationContext --- addApplicationListener添加事件监听器
将AbstractApplicationContext#applicationListeners注册到applicationEventMulticaster
getApplicationEventMulticaster().addApplicationListener(listener);
} String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); // #2 将上下文中的ApplicationListener注册到applicationEventMulticaster
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
} Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; // #3 发布在此之前已发生的事件
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}

6.构造热加载单例bean

AbstractApplicationContext --- finishBeanFactoryInitialization

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)); //#1 初始化ConversionService,后面注入属性要使用
} if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() { //#2 初始化StringValueResolver,用于解析bean属性引用的properties配置
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
} String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); //#3 初始化LoadTimeWeaverAware
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
} beanFactory.setTempClassLoader(null); beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons(); //#4 构造热加载单例bean
}

AbstractApplicationContext --- preInstantiateSingletons

public void preInstantiateSingletons() throws BeansException {
... List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames); for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { // #1 判断是否为非抽象类的热加载单例bean
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName); // #2 构造bean:如果非FactoryBean,构造bean。如果FactoryBean并且FactoryBean.isEagerInit为true,构造bean。
}
}
}
...
}

7. 完成刷新 finishRefresh

LifecycleProcessor也是spring提供的扩展点, 通过它可以在spring content start,stop,onRefresh等时刻自定义一些额外操作

protected void finishRefresh() {
// Initialize lifecycle processor for this context.
initLifecycleProcessor(); // #1 初始化LifecycleProcessor // Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh(); // #2 调用LifecycleProcessor#onRefresh()方法 // Publish the final event.
publishEvent(new ContextRefreshedEvent(this)); // #3 发布事件 // Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}

参考链接1


随心所往,看见未来。Follow your heart,see night!

*欢迎点赞、关注、留言,收藏及转发,一起学习、交流!

Spring之SpringContext的更多相关文章

  1. spring获取ApplicationContext对象的方法——ApplicationContextAware

    一. 引言 工作之余,在看一下当年学的spring时,感觉我们以前都是通过get~ set~方法去取spring的Ioc取bean,今天就想能不能换种模型呢?因为我们在整合s2sh时,也许有那么一天就 ...

  2. Spring.NET 与 NHibernate

    回到 Spring.NET & NHibernate of C#.NET 技术论坛 实战C#.NET编程----Spring.NET & NHibernate从入门到精通 您可以从以下 ...

  3. Spring引用测试

    上下文 using System; using Spring.Core; using Spring.Aop; using System; using Spring.Core; using Spring ...

  4. spring mvc 介绍

    Spring MVC Tutorial tag. * * If you do not want to deal with the intricities of the noscript * secti ...

  5. spring mvc和swagger整合

    pom.xml 导入jar jar包 所属 备注 spring-core spring spring核心包 spring-expression spring spEl表达式 spring-beans ...

  6. IDEA 初建Spring项目(Hello Spring)

    新建项目 在文件夹中建立一个项目文件 打开项目 打开IDEA,点击Open,根据所建项目路径找到该项目 依赖注入 点击项目名右键,点击new,点击file,创建pom.xml 内容为: <pro ...

  7. spring+spring mvc+JdbcTemplate 入门小例子

    大家使用这个入门时候 最好能够去 搜一下 spring mvc 的 原理,我放一张图到这里,自己琢磨下,后面去学习就容易了 给个链接 (网上一把,千万不能懒)    https://www.cnblo ...

  8. spring mvc mongoDb

    http://www.cnblogs.com/dennisit/p/3372568.html 系统环境: 操作系统:  windows xp 数 据 库:  mongodb2.0.6 驱 动 包: S ...

  9. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(6):Spring IOC容器学习(概念、作用、Bean生命周期)

    一.IOC控制反转概念 控制反转(IOC)是一种通过描述(在Java中可以是XML或者是注解)并通过第三方去生产或获取特定对象的方式. 主动创建模式,责任在于开发者,而在被动模式下,责任归于Ioc容器 ...

  10. Spring开发包介绍

    -----------------siwuxie095                         核心开发包         建立 Spring 工程时,需要引入 Spring 的开发包,否则无 ...

随机推荐

  1. 亚马逊云科技现身世界人工智能大会,揭示AI最新技术趋势

    2022世界人工智能大会(WAIC)于日前落幕.经过过去四届的发展与沉淀,今天的世界人工智能大会已成为人工智能领域最有影响力的国际盛会之一,今年大咖云集.国际大厂扎堆,充分彰显了大会的国际影响力和磁力 ...

  2. Windows 10无法显示无线网络连接

    最近刚刚升级了一下操作系统,升级到了1903版本.正好又有一个HP的打印机安装了一下.结果,发现居然无法管理无线网络了.如果看不到图,请点我. 右击选择连接,也无法显示SSID. 驱动是从这个官网下载 ...

  3. FastDFS配置文件思维导图(内含各配置文件详细参数说明)

  4. Go 源码解读|如何用好 errors 库的 errors.Is() 与 errors.As() 方法

    前言 快一个月没有更新技术文章了,这段时间投注了较多的时间学习字节的开源项目 Kitex/Hertz ,并维护一些简单的 issue ,有兴趣的同学也可以去了解: https://www.cloudw ...

  5. 关于VirtualBox在新建虚拟机时-选择操作系统类型后没有64位的版本选项

    今天笔者准备使用VirtualBox安装一台windows的虚拟时,在选项操作系统类型为Microsoft Windows后 发现下面的版本选择中,没有之前看到的64位选择,全是32位的,但实际昨天都 ...

  6. 带你认识JDK8中超nice的Native Memory Tracking

    摘要:从 OpenJDK8 起有了一个很 nice 的虚拟机内部功能: Native Memory Tracking (NMT). 本文分享自华为云社区<Native Memory Tracki ...

  7. YOLOv5】LabVIEW+OpenVINO让你的YOLOv5在CPU上飞起来

    前言 上一篇博客给大家介绍了使用opencv加载YOLOv5的onnx模型,但我们发现使用CPU进行推理检测确实有些慢,那难道在CPU上就不能愉快地进行物体识别了吗?当然可以啦,这不LabVIEW和O ...

  8. 路由组件构建方案(分库分表)V1

    路由组件构建方案V1 实现效果:通过注解实现数据分散到不同库不同表的操作. 实现主要以下几部分: 数据源的配置和加载 数据源的动态切换 切点设置以及数据拦截 数据的插入 涉及的知识点: 分库分表相关概 ...

  9. .NET Core C#系列之XiaoFeng.Threading.JobScheduler作业调度

    作业调度其实就是一个定时器,定时完成某件事, 比如:每分钟执行一次,每小时执行一次,每天执行一次,第二周几执行,每月几号几点执行,间隔多少个小时执行一次等. 作业类:XiaoFeng.Threadin ...

  10. 作用域通信对象:session用户在登录时通过`void setAttribute(String name,Object value)`方法设置用户名和密码。点击登录按钮后,跳转到另外一个页面显示用户

    作用域通信对象:session session对象基于会话,不同用户拥有不同的会话.同一个用户共享session对象的所有属性.作用域开始客户连接到应用程序的某个页面,结束与服务器断开连接.sessi ...