在之前的文章,笔者讨论的都是在用户第一次调用的时候触发的IOC过程,也就是所谓的lazy-init,下面看一下non-lazy-init,它是在IOC容器初始化的时候就把实例注入到了IOC容器中,它的思想是在容器完成对XML文件的BeanDefinition封装之后主动触发了该过程,具体过程和之前的IOC注入过程没有太大的区别,都是去调用getBean。不同就只有调用的触发对象和调用时间不同。
调用触发过程的对象是程序本身,而不是用户。
调用时间是IOC容器初始化时的refresh()方法,在完成对XML文件的封装之后调用的finishBeanFactoryInitialization(beanFactory);,具体代码如下:
// lazy-init
// AbstractApplicationContext类中
// 容器初始化
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//准备这个上下文进行刷新,设置其启动日期和活动标志,以及执行任何属性资源的初始化。
prepareRefresh();
//告诉子类刷新内部的bean工厂。调用refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//配置工厂的标准上下文特征,例如上下文的ClassLoader和后处理器。
prepareBeanFactory(beanFactory);
try {
// 允许在上下文子类中对bean工厂进行post-processing。
postProcessBeanFactory(beanFactory);
// 初始化这个上下文的消息源。
invokeBeanFactoryPostProcessors(beanFactory);
// 为此上下文初始化事件多播器。
registerBeanPostProcessors(beanFactory);
//初始化信息源,和国际化相关.
initMessageSource();
// 初始化此上下文的事件多播器。
initApplicationEventMulticaster();
// 在特定的上下文子类中初始化其他特殊的bean。
onRefresh();
// 检查监听器bean并注册它们。
registerListeners();
// 实例化所有剩下的(non-lazy-init)单例
finishBeanFactoryInitialization(beanFactory);
// 最后一步:发布相应的事件。
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已经存在的单例,防止资源浪费
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
}
// AbstractApplicationContext
// 完成BeanFactory上下文的初始化,初始化lazy-init的单例bean
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化此上下文的转换服务.
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));
}
// 如果没有bean的 post-processor
//(例如PropertyPlaceholderConfigurer bean)在之前注册了任何内容,
// 则注册一个默认的嵌入式值解析器:
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
//尽早初始化LoadTimeWeaverAware bean,以便尽早注册变换器。
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用临时ClassLoader进行类型匹配。
beanFactory.setTempClassLoader(null);
// 允许缓存所有的BeanDefinition元数据,不期望进一步的变化。
beanFactory.freezeConfiguration();
// 实例化所有剩下的(non-lazy-init)单例。
beanFactory.preInstantiateSingletons();
}
// DefaultListableBeanFactory
// 实例化所有的(non-lazy-init)单例。
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// 迭代一个副本以允许init方法,然后依次注册新的bean定义
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// 触发所有non-lazy的singleton beans初始化
for (String beanName : beanNames) {
// 如果指定的bean对应一个子bean定义
// 则返回一个合并的RootBeanDefinition,遍历父bean的定义。
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 是需要初始化的 bean
if (isFactoryBean(beanName)) {
// 是FactoryBean
// beanName前间"&",表示需要的是容器对象本身,
// 而不是容器产生的bean
// 并将其与FactoryBean创建的bean区分开来。
// 调用getBean方法,
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 {
// 不是FactoryBean 直接触发初始化过程
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// 触发所有适用的bean的后期初始化回调
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();
}
}
}
}