前言
前几篇文章已经说明Spring对BeanDefinition的解析与维护,在beans->bean标签定义下的bean 默认会通过 org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
方法注册到BeanFactory中,我们到目前为止,在BeanDefinition解析的链条中并没有发现有实例化Bean的行为,毕竟我们使用Bean时可以简单到使用getBean方法就能拿到一个实例化对象,那么Bean是何时被初始化的?带着这个疑问继续分析Spring源码,找到Bean初始化的真相。
源码
按照前几文的逻辑链,beanDefinition是在刷新ApplicationContext时注册进来的,那么回到org.springframework.context.support.AbstractApplicationContext.refresh()
方法
*下边有两个接口,如果不清楚作用和意义的话,可能影响阅读,可以看道某友的博文《Spring的BeanFactoryPostProcessor和BeanPostProcessor》 写的不错
org.springframework.beans.factory.config.BeanFactoryPostProcessor
org.springframework.beans.factory.config.BeanPostProcessor
借用道友的图,和部分文字(话说我之前怎么想不到这么说明问题呢……)
“而BeanPostProcessor的执行,取决于配置文件中bean的定义,如果定义的bean是singleton并且不是抽象类,也不延迟初始化,则BeanPostProcessor是在第11步中执行;而对于prototype的bean,BeanPostProcessor是在程序getBean的时候执行的。”
singleton 非延迟加载(non-lazy-init)
按文字说明来到第11步finishBeanFactoryInitialization(beanFactory)
其源码如下,其他都不重要,主要看beanFactory.preInstantiateSingletons();
这一行
/**
* 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));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
// 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.preInstantiateSingletons();
方法“Instantiate all remaining (non-lazy-init) singletons.”我们谷歌一下,其人话为“实例化所有剩下的(非懒惰init)单例。”这就很好理解了,所有非延迟加载的单例bean都在这个方法中实例化,那么是如何实例化的呢?ctrl+alt+b 试一下。正好直接看到这个方法实现只有一个,就是那位老朋友org.springframework.beans.factory.support.DefaultListableBeanFactory
这个类,下面分析一下这个类
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) { //日志(这是一种好的日志处理方式,当没有开启debug级别时,就会省下一次字符串拼接),spring源码里到处都是这样的处理,可以学习。
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 ,this.beanDefinitionNames 干嘛的,上文大概已有说明,可以结合《Spring 源码阅读 BeanFactory(二) 之registerBeanDefinition方法》一块看
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) { //遍历beanName
//这里先解释一下getMergedLocalBeanDefinition方法的含义,因为这个方法会常常看到。Bean定义公共的抽象类是AbstractBeanDefinition,普通的Bean在Spring加载Bean定义的时候,实例化出来的是GenericBeanDefinition,而Spring上下文包括实例化所有Bean用的AbstractBeanDefinition是RootBeanDefinition,这时候就使用getMergedLocalBeanDefinition方法做了一次转化,将非RootBeanDefinition转换为RootBeanDefinition以供后续操作。
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//非抽象的,单例的,非懒加载的
if (isFactoryBean(beanName)) { //Spring中有两种类型的Bean,一种是普通Bean,另一种是工厂Bean,即FactoryBean, 工厂Bean 再起炉灶
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if