这里所指的剩余的单例,其实就是非延迟加载单例。在Spring的源码中,是通过finishBeanFactoryInitialization的方法来执行的。我们按照惯例,先来看一张时序图。(相关资源可到这里下载:http://pan.baidu.com/s/1sjSo9a9)

首先Spring还是调用AbstractApplicationContext中的finishBeanFactoryInitialization的方法。这个方法中包括了ConversionService的设置、配置冻结及非延迟加载的bean的初始化工作。

/*** Finish the initialization of this context's bean factory,* initializing all remaining singleton beans.*/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));}// 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.beanFactory.setTempClassLoader(null);// Allow for caching all bean definition metadata, not expecting further changes.beanFactory.freezeConfiguration();// Instantiate all remaining (non-lazy-init) singletons.beanFactory.preInstantiateSingletons();}

上方法中,我们关心的是beanFactory.freezeConfiguration()和beanFactory.preInstantiateSingletons()的调用。其中一个beanFactory.freezeConfiguration()是冻结所有bean定义,说明注册的bean定义将不被修改或任何进一步的处理。而beanFactory.preInstantiateSingletons()是初始化剩下的单例(非惰性的)。

 @Overridepublic void freezeConfiguration() {this.configurationFrozen = true;this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);}
@Overridepublic 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.List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {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>() {@Overridepublic Boolean run() {return ((SmartFactoryBean<?>) factory).isEagerInit();}}, getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}else {getBean(beanName);}}}// Trigger post-initialization callback for all applicable beans...for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedAction<Object>() {@Overridepublic Object run() {smartSingleton.afterSingletonsInstantiated();return null;}}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}}}}

Spring源码之ApplicationContext(九)初始化剩余的单例相关推荐

  1. 第五篇:Spring源码篇-ApplicationContext

    Spring源码篇-ApplicationContext   前面通过手写IoC,DI.AOP和Bean的配置.到最后ApplicationContext的门面处理,对于Spring相关的核心概念应该 ...

  2. Spring源码之ApplicationContext

    ​ 本文是针对Srping的ClassPathXMLApplicationContext来进行源码解析,在本篇博客中将不会讲述spring Xml解析注册代码,因为ApplicationContext ...

  3. Spring源码解析-applicationContext.xml加载和bean的注册

    applicationContext文件加载和bean注册流程 ​ Spring对于从事Java开发的boy来说,再熟悉不过了,对于我们这个牛逼的框架的介绍就不在这里复述了,Spring这个大杂烩,怎 ...

  4. 【06】Spring源码-分析篇-ApplicationContext

    Spring源码篇-ApplicationContext   前面通过手写IoC,DI.AOP和Bean的配置.到最后ApplicationContext的门面处理,对于Spring相关的核心概念应该 ...

  5. 【Spring源码】4. 自己搞个标签?~自定义标签保姆级全过程(图解向,堆图预警)

    [Spring源码系列- IOC] 1 [Spring源码]0.安装Gradle环境 2 [Spring源码]1.下载与编译_pom relocation to an other version nu ...

  6. Spring 源码分析衍生篇十 :Last-Modified 缓存机制

    文章目录 一.前言 二.Last-Modify 三.实现方案 1. 实现 org.springframework.web.servlet.mvc.LastModified接口 1.1. 简单演示 1. ...

  7. Spring-bean的循环依赖以及解决方式___Spring源码初探--Bean的初始化-循环依赖的解决

    本文主要是分析Spring bean的循环依赖,以及Spring的解决方式. 通过这种解决方式,我们可以应用在我们实际开发项目中. 什么是循环依赖? 怎么检测循环依赖 Spring怎么解决循环依赖 S ...

  8. 四、spring源码解读初始化

    4.1.什么是IOC/DI? IOC(Inversion of Control)控制反转:所谓控制反转,就是把原先我们代码里面需要实现对象创建.依赖的代码,反转给容器来帮忙实现.那么必然的我们需要创建 ...

  9. spring源码 — 一、IoC容器初始化

    IoC容器初始化 注意:本次的spring源码是基于3.1.1.release版本 容器:具有获取Bean功能--这是最基本功能,也是BeanFactory接口定义的主要行为,在添加了对于资源的支持之 ...

  10. Spring源码解读(一)——容器是如何初始化的

    为什么要读源码 Spring是一群优秀的框架组成的社区.现在已经非常丰富了.当我们享受着Spring带来的便利同时,有时也想一探究竟. 人人都说Spring好,难免有人趋之若鹜,如果让你说出个究竟,你 ...

最新文章

  1. Java 垃圾回收机制,13张图给你讲清楚!
  2. java模拟数据库压测_写并发压测 java 脚本你必须会的 3 个类
  3. maven——pom.xml
  4. DBLINK 无统计信息导致SQL变慢
  5. python 数据库连接池_【转】Python 数据库连接池
  6. 0.8.11版本ffmpeg一天移植将近完成。
  7. cocos2d-x 是男人就下100层 附源码
  8. python str函数isdigit、isdecimal、isnumeric的区别
  9. 自己敲的low到爆炸的代码
  10. 降到3折的EasyRecovery了解下?
  11. SpringMVC实现AJax以及RestFull风格
  12. Queue--队列(c语言简单实现)
  13. matlab 求obb,obb包围盒代码
  14. 因使用率过低,谷歌翻译退出中国
  15. 光伏发电系统红外热图像(227幅图像,无标签,可用于识别蜗牛尾迹与热点故障)
  16. Android 选择文件(调用系统文件管理器)
  17. 第一财经专访李旭阳:反诈骗、管控金融风险,腾讯安全发力联邦学习技术
  18. sql2005java驱动_sqljdbc.jar 2005
  19. mysql endwith_endwith与startwith字符串方法匹配重写
  20. 开关二极管和肖特基二极管比较

热门文章

  1. js 对象的_proto_属性 和函数的prototype属性分析
  2. 移动 web 1px 边框解决方案
  3. JavaScript实现对象的深度克隆及typeof和instanceof【简洁】【分享】
  4. 【Linux】linux经常使用基本命令
  5. vlc的应用之四:vlc的Mozilla Plugin
  6. [导入]关于中文文本的截取
  7. Tomcat详解(十一)——Tomcat管理
  8. Jupyter notebook内使用(添加)虚拟环境
  9. 理解Cookie,Session,Token
  10. Leetcode 刷题笔记(十八) —— 二叉树篇之二叉搜索树的修改与构造