ApplicationContext(九)初始化非延迟的 bean

此至,ApplicationContext 已经完成了全部的准备工作,开始初始化剩余的 bean 了(第 11 步)。

public void refresh() throws BeansException, IllegalStateException {
// 11. 初始化剩余的 bean (部分在 invokeBeanFactoryPostProcessors 已经初始化)
finishBeanFactoryInitialization(beanFactory);
}

finishBeanFactoryInitialization 主要是实例化非懒加载的 bean。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 1. 注册 ConversionService,注意 beanName 必须为 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));
} // 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); // 2. 冻结所有的 bean 定义,说明注册的 bean 定义将不被修改
beanFactory.freezeConfiguration(); // 3. 初始化剩下的 bean
beanFactory.preInstantiateSingletons();
}

一、注册 ConversionService

(1) String2DateConverter

public class String2DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
return sdf.parse(source);
} catch (ParseException e) {
;
}
return null;
}
}

(2) 注册

注意:beanName 必须为 conversionService

<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.github.binarylei.spring01.day0728.conversionservice.String2DateConverter"/>
</set>
</property>
</bean>

(3) 测试

@Test
public void test() {
DefaultConversionService service = new DefaultConversionService();
service.addConverter(new String2DateConverter()); Date value = service.convert("2018-08-02", Date.class);
System.out.println(value);
}

二、冻结配置

源代码【DefaultListableBeanFactory】

public void freezeConfiguration() {
this.configurationFrozen = true;
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}

三、初始化非延迟加载

public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
} // 1. 创建剩下的单实例 bean
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>() {
@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. 筛选出实现了 SmartInitializingSingleton 接口的 bean,回调 afterSingletonsInstantiated() 方法
// @EventListener 注解的方式注册监听器就是在这一步完成的
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>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}

每天用心记录一点点。内容也许不重要,但习惯很重要!

ApplicationContext(九)初始化非延迟的 bean的更多相关文章

  1. spring源码分析系列5:ApplicationContext的初始化与Bean生命周期

    回顾Bean与BeanDefinition的关系. BeanFactory容器. ApplicationContext上下文. 首先总结下: 开发人员定义Bean信息:分为XML形式定义:注解式定义 ...

  2. Spring源码分析(二十四)初始化非延迟加载单例

    摘要: 本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 完成BeanFactory的初始化工作,其中包括ConversionS ...

  3. 7 -- Spring的基本用法 -- 4... 使用 Spring 容器:Spring 容器BeanFactory、ApplicationContext;ApplicationContext 的国际化支持;ApplicationContext 的事件机制;让Bean获取Spring容器;Spring容器中的Bean

    7.4 使用 Spring 容器 Spring 有两个核心接口:BeanFactory 和 ApplicationContext,其中ApplicationContext 是 BeanFactory ...

  4. spring源码分析6: ApplicationContext的初始化与BeanDefinition的搜集入库

    先前几篇都是概念的讲解:回顾下 BeanDefinition 是物料 Bean是成品 BeanFactory是仓库,存储物料与成品 ApplicationContext初始化搜集物料入库,触发生产线, ...

  5. 【转】forbids in-class initialization of non-const static member不能在类内初始化非const static成员

    转自:forbids in-class initialization of non-const static member不能在类内初始化非const static成员 今天写程序,出现一个新错误,好 ...

  6. Error creating bean with name 'mapper' defined in class path resource [applicationcontext.xml]: Cannot resolve reference to bean 'factory' while setting bean property 'sqlSessionFactory'; nested excep

    Error creating bean with name 'mapper' defined in class path resource [applicationcontext.xml]: Cann ...

  7. Spring学习记录(九)---通过工厂方法配置bean

    1. 使用静态工厂方法创建Bean,用到一个工厂类 例子:一个Car类,有brand和price属性. package com.guigu.spring.factory; public class C ...

  8. 关于ApplicationContext的初始化

    一.提倡的初始化方法:<1>在独立应用程序中,获取ApplicationContext:          AbstractApplicationContext context = new ...

  9. Spring MVC 上下文(ApplicationContext)初始化入口

    Spring 常用上下文容器有哪些 ApplicationContext ClassPathXmlApplicationContext ApplicationContext context = new ...

随机推荐

  1. Python Try Except

    Python Try: Except Except 类型一: try: file_size = os.path.getsize('maoyan.csv'); except OSError as err ...

  2. CentOS7下解决yum install mysql-server没有可用包

    # wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm --  http://repo.mysql.com/mysq ...

  3. 搭建jsp渗透测试环境

    java运行环境下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html fir ...

  4. Structured streaming

    Structured streaming是spark 2.0以后新增的用于实时处理的技术.与spark streaming不同的是,Structured streaming打开了数据源到数据落地之间的 ...

  5. AS不能真机调试 (转)

    经常遇到这种问题 现总结一下原因 打开手机的开发人员选项,允许USB调试 AS--->tools--->android-->Enable ADB Interation选项 勾上. A ...

  6. 关于JavaScript全局作用域和函数作用域的拙见

    在类c的语言中,用{}引起来的部分称为块级作用域,而在JS中没有块级作用域 作用域:一个变量作用的范围:中Js中一共有两种作用: 全局作用域 - 直接编写在script标签中的JS代码,都在全局作用域 ...

  7. pta l2-7(家庭房产)

    题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805068539215872 题意:给定n个人的信息,包括其编号 ...

  8. 查看linux发行版版本

    可以通过查看/etc/issue文件查看发行版版本号,不论系统是redhat\suse\debian

  9. word2vec详解与实战

    有那么一句话 不懂word2vec,就别说自己是研究人工智能->机器学习->自然语言处理(NLP)->文本挖掘的 所以接下来我就从头至尾的详细讲解一下word2vec这个东西. 简要 ...

  10. ACM-ICPC 2018 沈阳赛区网络预赛 F. Fantastic Graph (贪心或有源汇上下界网络流)

    "Oh, There is a bipartite graph.""Make it Fantastic."X wants to check whether a ...