spring初始化的前置操作
spring真正开始实例化之前,会有一些操作,该笔记,主要来记录真正调用后置处理器之前的处理逻辑
spring的实例化,是通过调用一系列的后置处理器来完成
前面有说到过,spring对bean的操作,是在refresh方法中完成的,finishBeanFactoryInitialization是对beanDefinitionMap集合中的bean进行实例化的
org.springframework.context.support.AbstractApplicationContext#refresh
org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
在这个方法中,主要完成了以下几个操作:
* 1.遍历所有的beanDefinitionName,完成合并bean的操作 * 2.如果当前bean是单实例的、非懒加载的、非抽象bean,就调用bean的后置处理器 完成实例化的操作 * 3.在所有bean都实例化完成之后,调用实现了SmartInitializingSingleton接口的bean对象,完成org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()方法的调用
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isDebugEnabled()) {
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.
/**
* 在将beanDefinition存入BeanDefinitionMap的同时,会将beanName存入到一个list集合中
* 这里直接从beanDefinitionNames这个集合中,获取所有要实例化的bean的name
*/
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
//触发所有非延迟加载单实例bean的加载,加载的过程就是调用getBean()方法 上面获取到的是所有的beanName
for (String beanName : beanNames) {
/**
* 合并父类beanDefinition;在前面初始化bean的时候,就已经合并了,这里是再判断一次,如果当前bean没有合并,就合并;如果已经合并了,就直接从
* 对应的map集合中取出合并之后的beanDefinition
*
* 之所以要做beanDefinition的merge操作,是因为有些beanDefinition是RootBeanDefinition的子类,如果直接用子BeanDefinition去实例化,可能会有问题
* 因为一个子BeanDefinition可以继承父beanDefinition,一些共性的信息可以放到父BeanDefinition中,所以,在对bean进行初始化的时候,都要对相应的beanDefinition进行合并的操作,得到RootBeanDefinition;比如:
* RootBeanDefinitionA设置需要注入name属性
* BeanDefinitionB设置需要注入type属性,再设置BeanDefinitionB 继承RootBeanDefinitionA,假如在这里不合并rootBeanDefinitionA,那么B这个bd需要注入的属性就只有type,不会有name,那也就不是我们想要的bd了;所以这里要把子bd的属性合并到新的RootBeanDefinition中
*
* 并且,spring在初始化bean的过程中,会对bd进行一些校验(比如:是否是单实例的,是否是抽象的等);所以:这里要先把bd进行合并,获取到父类的bd属性信息
*/
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 非抽象、非懒加载、单实例的bean
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//判断当前bean是否是beanFactory;如果是factoryBean,在beanName前面加上 &
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);
}
}
}
// Trigger post-initialization callback for all applicable beans...
/**
* 这里应该也算是spring提供的一个扩展点之一
* 在所有的bean都实例化完成之后,会调用org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()
* 来完成程序员的一些业务逻辑操作
*/
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();
}
}
}
}
核心的操作是getBean()方法,在getBean()方法中,会调用到org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean方法