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 内部工作机制(一)的更多相关文章

  1. spring 内部工作机制(二)

    本章节讲Spring容器从加载配置文件到创建出一个完整Bean的作业流程及参与的角色. Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表, ...

  2. Spring容器技术内幕之内部工作机制

    引言 Spring容器就像一台构造精妙的机器,我们通过配置文件向机器传达控制信息,机器就能够按照设定的模式工作.如果将Spring容器比作一辆车,那么可以将BeanFactory看成汽车的发动机,而A ...

  3. Spring学习记录2——简单了解Spring容器工作机制

    简单的了解Spring容器内部工作机制 Spring的AbstractApplicationContext是ApplicationContext的抽象实现类,该抽象类的refresh()方法定义了Sp ...

  4. Spring Ioc工作机制 初步

    Spring IoC工作原理 Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表,然后根据这张注册表实例化Bean,装配好Bean之间的依赖 ...

  5. 【转】Java学习---HashMap和HashSet的内部工作机制

    [原文]https://www.toutiao.com/i6593863882484220430/ HashMap和HashSet的内部工作机制 HashMap 和 HashSet 内部是如何工作的? ...

  6. Spring是什么,Spring容器提供了那些功能,Spring的工作机制

    spring是什么 spring 是一个轻型的容器,是J2EE规范的轻量级实现,可以一站式开发,其中提供了,bean工厂,用以构造我们需要的Model ,spring 是非侵入式的,spring应用中 ...

  7. 浅析Spring MVC工作机制

    1.如何使用Spring MVC? 在web.xml中配置一个DispatcherServlet DispatchServlet初始化的时候会去寻找一个在应用程序的WEB-INF目录下的配置文件,命名 ...

  8. (spring-第5回【IoC基础篇】)spring容器从加载配置文件到实例化bean的内部工作机制

    前面讲过,spring的生命周期为:实例化前奏-->实例化-->实例化后期-->初始化前期-->初始化-->初始化后期-->bean的具体调用-->销毁前-- ...

  9. 实例说明C++的virtual function的作用以及内部工作机制初探

    C++为何要引入virtual function? 来看一个基类的实现: 1 class CBase 2 { 3 public: 4 CBase(int id) : m_nId(id), m_pBas ...

随机推荐

  1. ASP.NET Core Razor 视图组件

    视图组件简介 在新的ASP.NET Core MVC中,视图组件类似于局部视图,但它们更强大.视图组件不使用模型绑定,仅依赖于您在调用时提供的数据. 视图组件特性: 呈现页面响应的某一部分而不是整个响 ...

  2. 关于Meta标签中format-detection属性及含义

    一.Meta标签中的format-detection属性及含义 意为:格式检测 或许你会有这样的经历:当你在制作手机端的页面中,点击了没有加任何链接的格式的数字时,这时手机会进行自动拔号提示操作! 禁 ...

  3. 一种解决url的get请求参数传值乱码问题的方式

    做项目的时候发现url get请求传中文字符出现乱码问题,百度了一下,最后用一种比较容易理解的方式解决了.分享给大家! 经过百度,网友提到:url get方式提交的参数编码,只支持iso8859-1编 ...

  4. Android studio 一些技术添加依赖,依赖库

    Recyclerview compile 'com.android.support:recyclerview-v7:21.0.+' butterKnife 的依赖compile 'com.jakewh ...

  5. 浏览器事件window.onload、o…

    原文地址:浏览器事件window.onload.onfocus.onblur.onscroll和resize作者:lilyxiao <html> <head> <titl ...

  6. MiniProfiler工具

    MiniProfiler工具介绍   MiniProfiler是一款针对.NET, Ruby, Go and Node.js的性能分析的轻量级程序.可以对一个页面本身,及该页面通过直接引用.Ajax. ...

  7. 必应词典--英语学习APP案例分析

    一.调研,评测 1.个人上手体验 这还是第一次听说必应词典,只能说知名度有待提高啊.首先,下载打开必应词典的第一感觉就是不够美观,个人感觉不论图标还是界面的美感都不足,既繁琐有简洁,给人的最直观感受就 ...

  8. 扫雷游戏制作过程(C#描述):第二节、界面设计

    前言 这里给出教程原文地址. 该项目已经放在github上托管. 扫雷界面设计 界面的设计,首先需要创建一个菜单栏.具体方法在左边找到工具箱窗口,展开其中的菜单和工具栏,找到MenuStrip选项,双 ...

  9. 201521123063 《java程序设计》第六周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖 ...

  10. 201521123078《Java程序设计》第2周学习总结

    1. 本周学习总结 **学会使用码云管理代码,包括将本地的代码上传至码云,和将码云上的项目保存至本地.编程要掌握重要的类名的使用,提高编程效率,避免想无头苍蝇一样** 2. 书面作业 使用Eclips ...