ApplicationContext(九)初始化非延迟的 bean
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的更多相关文章
- spring源码分析系列5:ApplicationContext的初始化与Bean生命周期
回顾Bean与BeanDefinition的关系. BeanFactory容器. ApplicationContext上下文. 首先总结下: 开发人员定义Bean信息:分为XML形式定义:注解式定义 ...
- Spring源码分析(二十四)初始化非延迟加载单例
摘要: 本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 完成BeanFactory的初始化工作,其中包括ConversionS ...
- 7 -- Spring的基本用法 -- 4... 使用 Spring 容器:Spring 容器BeanFactory、ApplicationContext;ApplicationContext 的国际化支持;ApplicationContext 的事件机制;让Bean获取Spring容器;Spring容器中的Bean
7.4 使用 Spring 容器 Spring 有两个核心接口:BeanFactory 和 ApplicationContext,其中ApplicationContext 是 BeanFactory ...
- spring源码分析6: ApplicationContext的初始化与BeanDefinition的搜集入库
先前几篇都是概念的讲解:回顾下 BeanDefinition 是物料 Bean是成品 BeanFactory是仓库,存储物料与成品 ApplicationContext初始化搜集物料入库,触发生产线, ...
- 【转】forbids in-class initialization of non-const static member不能在类内初始化非const static成员
转自:forbids in-class initialization of non-const static member不能在类内初始化非const static成员 今天写程序,出现一个新错误,好 ...
- 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 ...
- Spring学习记录(九)---通过工厂方法配置bean
1. 使用静态工厂方法创建Bean,用到一个工厂类 例子:一个Car类,有brand和price属性. package com.guigu.spring.factory; public class C ...
- 关于ApplicationContext的初始化
一.提倡的初始化方法:<1>在独立应用程序中,获取ApplicationContext: AbstractApplicationContext context = new ...
- Spring MVC 上下文(ApplicationContext)初始化入口
Spring 常用上下文容器有哪些 ApplicationContext ClassPathXmlApplicationContext ApplicationContext context = new ...
随机推荐
- 小程序 css3走马灯效果
<view class='notable-container' style='background:#ffffff;'> <view style='z-index:2000;back ...
- js 统计数组中元素的个数
var all = "02 06 11 12 19 29 09 10 12 19 22 29 08 11 13 19 28 31 07 08 09 15 22 27 10 18 19 29 ...
- spring init method destroy method
在java的实际开发过程中,我们可能常常需要使用到init method和destroy method,比如初始化一个对象(bean)后立即初始化(加载)一些数据,在销毁一个对象之前进行垃圾回收等等. ...
- linux中awk命令学习
awk是一个强大的文本分析工具,awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理. 通常获取某一行时,我们会使用 “grep 关键字“进行查找,但在读取某一列时, ...
- idea 安装和破解
https://blog.csdn.net/SmileLvCha/article/details/78936659
- 自定义sql server 聚合涵数
using System; using System.Data; using System.Data.SqlClient; using System.Data.SqlTypes; using Micr ...
- Beef的使用
应用普遍转移到B/S架构,浏览器成为统一客户端程序 通过注入JS脚本,利用浏览器攻击其他网站 ruby编写 攻击手段 利用网站XSS漏洞实现攻击 诱使客户端访问含有hook的伪造站点 结合中间人攻击注 ...
- git和svn的对比
- TOJ3097: 单词后缀 (字典树 or map瞎搞)
传送门 (<---可以点击的~) 时间限制(普通/Java):1000MS/3000MS 内存限制:65536KByte 描述 有些英语单词后缀都是一样的,现在我们需要从给定的一堆单词里 ...
- JS获取鼠标左(右)滑事件
鼠标左(右)滑也是网站开发中常见的效果之一,这里对鼠标左(右)滑做出一些解释. 首先要获取需要左右滑事件的节点: eg: var div=document.getElementById("d ...