spring 内部工作机制(一)
Spring内部机制的内容较多,所以打算多分几个阶段来写。
本章仅探索Spring容器启动做了哪些事;
前言:
都说Spring容器就像一台构造精妙的机器,此话一点不假,我们通过配置文件向机器传达控制信息,机器就能够按照设定的模式工作。
如果我们将Spring容器比喻为一辆汽车,可以将BeanFactory看成汽车的发动机,而ApplicationContext则是整辆汽车,它不但包括发动机,还包括离合器,变速器及底盘,车身,电器设备等其他组件,在ApplicationContext内,各个组件按部就班地完成汽车的各项功能。
正文:
Spring的AbstractApplicationContext是ApplicationContext的抽象实现类,该抽象类的refresh( )方法定义了Spring容器在加载配置文件后的各项处理过程,非常清晰。
我们来看一下这个方法内部定义了哪些执行逻辑。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh(); // ① 初始化BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory); try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory); // ② 调用工厂后处理器
invokeBeanFactoryPostProcessors(beanFactory); // ③ 注册Bean后处理器
registerBeanPostProcessors(beanFactory); // ④ 初始化消息源
initMessageSource(); // ⑤ 初始化应用上下文事件广播器
initApplicationEventMulticaster(); // ⑥ 初始化其他特殊的Bean,由具体子类实现
onRefresh(); // ⑦ 注册事件监听器
registerListeners(); // ⑧ 初始化所有单实例的Bean,使用懒加载模式的Bean除外
finishBeanFactoryInitialization(beanFactory); // ⑨ 完成刷新并发布容器刷新事件
finishRefresh();
} catch (BeansException ex) {
//略
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
共九种主要的处理操作。下面再详细说说这些操作。
(1) 初始化BeanFactory: 根据配置文件实例化BeanFactory,在obtainFreshBeanFactory()方法中,首先调用refreshBeanFactory()方法刷新BeanFactory,然后调用getBeanFactory()方法获取BeanFactory,
这两个方法都是由具体子类实现的,在这一步里,Spring将配置文件的信息装入容器的Bean定义注册表(BeanDefinitionRegistry)中,但此时Bean还未初始化。
附上obtainFreshBeanFactory()方法的源码如下:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
(2) 调用工厂后处理器: 根据反射机制从BeanDefinitionRegistry中找出所有实现了BeanFactoryPostProcessor接口的Bean,并调用其postProcessBeanFactory()接口方法。也附上部分源码吧。
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
new LinkedList<BeanDefinitionRegistryPostProcessor>(); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryPostProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
registryPostProcessors.add(registryPostProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
(3) 注册Bean后处理器: 根据反射机制从BeanDefinitionRegistry中找出所有实现了BeanPostProcessor接口的Bean,并将它们注册到容器Bean后处理器的注册表中。
(4) 初始化消息源: 初始化容器的国际化消息资源。想必这个比较好理解。
(5) 初始化应用上下文事件广播器。
(6) 初始化其他特殊的Bean: 这是一个钩子方法,子类可以借助这个方法执行一些特殊的操作,如AbstractRefreshableWebApplicationContext就使用该方法执行初始化ThemeSource的操作。
(7) 注册事件监听器。
(8) 初始化所有单实例的Bean,使用懒加载模式的Bean除外:初始化Bean后,将它们放入Spring容器的缓存池中。(加一句:如果这个有懒加载标志的单实例Bean被一个非懒加载的单实例Bean引用时,那么懒加载失效)
(9) 发布上下文刷新事件: 创建上下文刷新事件,事件广播器负责将这些事件广播到每个注册的事件监听器中。(关于事件的内容在下面的章节会有详解)
下一章节讲Spring容器从加载配置文件到创建出一个完整Bean的作业流程及参与的角色。
spring 内部工作机制(一)的更多相关文章
- spring 内部工作机制(二)
本章节讲Spring容器从加载配置文件到创建出一个完整Bean的作业流程及参与的角色. Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表, ...
- Spring容器技术内幕之内部工作机制
引言 Spring容器就像一台构造精妙的机器,我们通过配置文件向机器传达控制信息,机器就能够按照设定的模式工作.如果将Spring容器比作一辆车,那么可以将BeanFactory看成汽车的发动机,而A ...
- Spring学习记录2——简单了解Spring容器工作机制
简单的了解Spring容器内部工作机制 Spring的AbstractApplicationContext是ApplicationContext的抽象实现类,该抽象类的refresh()方法定义了Sp ...
- Spring Ioc工作机制 初步
Spring IoC工作原理 Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表,然后根据这张注册表实例化Bean,装配好Bean之间的依赖 ...
- 【转】Java学习---HashMap和HashSet的内部工作机制
[原文]https://www.toutiao.com/i6593863882484220430/ HashMap和HashSet的内部工作机制 HashMap 和 HashSet 内部是如何工作的? ...
- Spring是什么,Spring容器提供了那些功能,Spring的工作机制
spring是什么 spring 是一个轻型的容器,是J2EE规范的轻量级实现,可以一站式开发,其中提供了,bean工厂,用以构造我们需要的Model ,spring 是非侵入式的,spring应用中 ...
- 浅析Spring MVC工作机制
1.如何使用Spring MVC? 在web.xml中配置一个DispatcherServlet DispatchServlet初始化的时候会去寻找一个在应用程序的WEB-INF目录下的配置文件,命名 ...
- (spring-第5回【IoC基础篇】)spring容器从加载配置文件到实例化bean的内部工作机制
前面讲过,spring的生命周期为:实例化前奏-->实例化-->实例化后期-->初始化前期-->初始化-->初始化后期-->bean的具体调用-->销毁前-- ...
- 实例说明C++的virtual function的作用以及内部工作机制初探
C++为何要引入virtual function? 来看一个基类的实现: 1 class CBase 2 { 3 public: 4 CBase(int id) : m_nId(id), m_pBas ...
随机推荐
- EF实例创建问题
场景:CodeFirst 情况下,在控制器新建一个EF数据库对象,以便运行时进行表的初始化创建 Private DemoContext db=new DemoContext (): 问题:什么时候释放 ...
- Java基础学习 —— 对象的克隆
对象的克隆分为对象的浅克隆和深克隆 一.对象的浅克隆 注意事项: 1.如果一个对象需要调用clone的方法克隆,那么该对象必须要实现Cloneable接口 2.Cloneable对象只是一个标识对象, ...
- webStrom2017.1版本如何添加vue.js插件
第一步:打开webStrom-setting 第二步:选择File and Code Templates--点击左上角"+"号 第三步:在Name:vue File Exte ...
- OpenSSL中的大数接口与基于其的自用RSA加密接口设计
本文记录了初次接触OpenSSL中的大数模块,重温了RSA加密流程,使用OpenSSL的接口包装成自用RSA加密接口,并且利用自己的接口演示了Alice与Bob通过RSA加密进行通讯的一个示例. 概览 ...
- MySQL (三)-- 字段属性、索引、关系、范式、逆规范化
1 字段属性 主键.唯一键和自增长. 1.1 主键 主键:primary key,一张表中只能有一个字段可以使用对应的键,用来唯一的约束该字段里面的数据,不能重复. 一张表只能有最多一个主键. 1.1 ...
- 团队作业3-需求改进&原型设计
选题:实验室报修系统 实验室设备经常会发生这样或那样的故障,靠值班人员登记设备故障现象,维护人员查看故障记录,进行维修,然后登记维修过程与内容,以备日后复查,用这种方式进行设备运营管理,它仅仅起到一个 ...
- 201521123095 《Java程序设计》第5周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 1.1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误.并分析输出 ...
- 201521123028《Java程序设计》第1周学习总结
1. 本周学习总结 通过本周的学习: 1.了解了Java的发展史(从OAK转向Internet,并逐步发展至今的历程) 2.与C语言比较,Java语言的特点: ①将源程序编译成一种结构中立的中间文件格 ...
- PHP面向对象简单总结
类和对象对象:一切东西都可以看做对象,对象是类的实例化.类:类是对象的抽象,用来描述众多对象共有的特征. 定义类 class成员变量 和 成员方法访问修饰符 public共有的 private 私有的 ...
- Java:双括号初始化 /匿名内部类初始化法
偶然见到一种初始化方式,感到十分新奇: //新建一个列表并赋初值A.B.C ArrayList<String> list = new ArrayList<String>() { ...