【Spring 源码】ApplicationContext 容器的加载原理(六)
一、提前对非延迟加载的 Bean 实例化
主要代码:finishBeanFactoryInitialization(beanFactory);
1. 源码解析
【1】结束容器初始化
主要代码:finishBeanFactoryInitialization()
完成容器初始化的最后一步,会提前对非延迟加载的 Bean 进行初始化,等待用户调用 getBean()
的时候获取,提高系统的性能。
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));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 清空临时的 ClassLoader
beanFactory.setTempClassLoader(null);
// 冻结设置,不再进行修改
beanFactory.freezeConfiguration();
// 初始化剩余的 Bean
beanFactory.preInstantiateSingletons();
}
【2】提前对 Bean 进行实例化
主要代码:preInstantiateSingletons()
提前对 Bean 进行实例化的过程中,会判断 Bean 是否为抽象类,并且 Bean 的作用域需要为 Singleton,否则不能进行实例化。并且 Bean 如果配置了 lazy-init,则会在获取 Bean 的过程中才会实例化,而不是在容器初始化过程中进行实例化。
同时 xml 文件中 注册了 SmartInitializingSingleton 类型的 Bean ,则会在 Bean 完成实例化结束后,可以调用 afterSingletonsInstantiated()
来对 Bean 实例进行后处理。
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 对所有不是设定为 lazy-init 的 Bean 进行初始化
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 判断 Bean 不是抽象并且不是设定为 lazy-init 的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
// 进行 Bean 实例化
getBean(beanName);
}
}
}
// 对 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<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}