1、开始位置
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
@Override
// 在创建IOC容器前,如果已经有容器存在,则需要把已有的容器销毁和关闭,在重新建立新容器。
// 在新建立的容器中,对容器进行初始化,对BeanDefinition资源进行载入
public void refresh() throws BeansException, IllegalStateException {
·
·
·
·
·
·
// 初始化所有剩余的单例Bean
// 这里是对容器lazy-init属性进行处理的入口方法
finishBeanFactoryInitialization(beanFactory);
·
·
·
·
·
·
}
}
2、finishBeanFactoryInitialization() 源码
- 对注册后的Bean进行预实例化所谓预实例化就是DI,也就是调用getBean方法
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
//对配置了lazy-init属性的Bean进行预实例化处理
// lazy-init 默认false, 即Spring默认就是预实例化
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//这是Spring3以后新加的代码,为容器指定一个转换服务(ConversionService) ,对某些Bean属性进行转换时使用
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后置处理器(如 PropertyPlaceholderConfigurer bean),请注册默认嵌入值的 解析器:主要用于解析注解属性
if (!beanFactory.hasEmbeddedValueResolver()) {
//添加嵌入值解析器
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 尽早初始化LoadTimeWeaverAware bean,以便尽早注册其转换器。
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
//依赖注入过程
getBean(weaverAwareName);
}
//为了类型匹配,停止使用临时的类加载器
beanFactory.setTempClassLoader(null);
//缓存容器中所有注册的BeanDefinition元数据,以防被修改
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
//对配置了lazy-init属性的单态模式Bean进行预实例化处理
beanFactory.preInstantiateSingletons();
}
}
2、DefaultListableBeanFactory
ConfigurableListableBeanFactory是一个接口,preInstantiateSingletons方法由子类DefaultListableBeanFactory实现。
2.1、主要源码
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
@Override
//对配置lazy-init属性 单例Bean的预实例化
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("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.
// 此处目的,把所有的 bean 定义信息名称,赋值到一个新的集合中
List beanNames = new ArrayList<>(this.beanDefinitionNames);
// 触发所有non-lazy 单例bean的初始化
for (String beanName : beanNames) {
//获取指定名称的Bean定义
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//Bean不是抽象的,是单例模式的,且lazy-init属性配置为false
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//如果指定名称的bean是创建容器的Bean,
if (isFactoryBean(beanName)) {
Object bean = getBean("&" + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean> factory = (FactoryBean>) bean;
// 是否渴望初始化
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction)
((SmartFactoryBean>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
//依赖注入,也就是DI
getBean(beanName);
}
}
}
// 触发所有applicable bean的初始化后 的回调
for (String beanName : beanNames) {
//获取单例
Object singletonInstance = getSingleton(beanName);
//智能初始化单例(我也不知道是干嘛用的,猜测可能是初始化之后还有动作吧)
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
3、总结
如果设置了lazy-init=false(默认false),则容器在完成Bean定义的注册之后,会通过getBean方法,触发对指定Bean的初始化和依赖注入过程,这样当应用第一次向容器索取所需的Bean时,容器不再需要对Bean进行初始化和依赖注入,直接缓存中取,这样就提高了第一次获取Bean的性能。



