- 前言
- 第一部分 核心实现
- 第 1 章 Spring 整体架构和环境搭建
- 第 2 章 容器的基本实现
- 第 3 章 默认标签的解析
- 第 4 章 自定义标签的解析
- 第 5 章 bean 的加载
- 第 6 章 容器的功能扩展
- 第 7 章 AOP
- 第二部分 企业应用
- 第 8 章 数据库连接 JDBC
- 第 9 章 整合 MyBatis
- 第 10 章 事务
- 第 11 章 SpringMVC
- 第 12 章 远程服务
- 第 13 章 Spring 消息
6.7 初始化非延迟加载单例
完成 BeanFactory 的初始化工作,其中包括 ConversionService 的设置、配置冻结以及非延迟加载的 bean 的初始化工作。
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);
//冻结所有的 bean 定义,说明注册的 bean 定义将不被修改或任何进一步的处理。
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
//初始化剩下的单实例(非惰性的)
beanFactory.preInstantiateSingletons();
}
首先我们来了解一下 ConversionService 类所提供的作用。
1.ConversionService 的设置
之前我们提到过使用自定义类型转换器从 String 转换为 Date 的方式,那么,在 Spring 中还提供了另一种转换方式:使用 Converter。同样,我们使用一个简单的示例来了解下 Converter 的使用方式。
(1)定义转换器。
public class String2DateConverter implements Converter<String, Date> {
@Override
public Date convert(String arg0) {
try {
return DateUtils.parseDate(arg0,
new String[] { "yyyy-MM-dd HH:mm:ss" });
} catch (ParseException e) {
return null;
}
}
}
(2)注册。
<bean id="conversionService"
class="org.Springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="String2DateConverter" />
</list>
</property>
</bean>
(3)测试。
这样便可以使用 Converter 为我们提供的功能了,下面我们通过一个简便的方法来对此直接测试。
public void testStringToPhoneNumberConvert() {
DefaultConversionService conversionService = new DefaultConversionService();
conversionService.addConverter(new StringToPhoneNumberConverter());
String phoneNumberStr = "010-12345678";
PhoneNumberModel phoneNumber = conversionService.convert(phoneNumberStr, PhoneNumber
Model.class);
Assert.assertEquals("010", phoneNumber.getAreaCode());
}
通过以上的功能我们看到了 Converter 以及 ConversionService 提供的便利功能,其中的配置就是在当前函数中被初始化的。
2.冻结配置
冻结所有的 bean 定义,说明注册的 bean 定义将不被修改或进行任何进一步的处理。
public void freezeConfiguration() {
this.configurationFrozen = true;
synchronized (this.beanDefinitionMap) {
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.bean
DefinitionNames);
}
}
3.初始化非延迟加载
ApplicationContext 实现的默认行为就是在启动时将所有单例 bean 提前进行实例化。提前实例化意味着作为初始化过程的一部分,ApplicationContext 实例会创建并配置所有的单例 bean。通常情况下这是一件好事,因为这样在配置中的任何错误就会即刻被发现(否则的话可能要花几个小时甚至几天)。而这个实例化的过程就是在 finishBeanFactoryInitialization 中完成的。
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isInfoEnabled()) {
this.logger.info("Pre-instantiating singletons in " + this);
}
List<String> beanNames;
synchronized (this.beanDefinitionMap) {
// 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.
beanNames = new ArrayList<String>(this.beanDefinitionNames);
}
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>() {
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
}
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论