目录
之所以先写了ApplicationContext的refresh方法再写继续写BeanFactory的getBean核心方法,是因为觉得项目中根本不会直接使用BeanFactory肯定还是会使用ApplicationContext。并且每个Bean的生命周期会在getBean中完成,其中就会回调所有的BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法。
先梳理一下getBean的整个过程(只分析单利Bean)
1、首先会从缓存中获取;否则(第一次)需要根据之前注入的BeanDefinition进行创建。
2、创建之前需要先处理ovverride和前置准备;在创建时会有依赖注入的情况(需要解决循环依赖的问题),则再分析真正的创建
3、创建过程:创建Bean实例;记录创建Bean的工厂;属性注入;初始化Bean(Bean的生命周期在这里完成,包括注册DisposableBean)
开始:
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
// 省略
}
1、获取真实的BeanName(传入的可能是别名等)
调用getBean方法时候,传入的字符串可能是别名,或者是FactoryBean类型则可能传入&开头的,以获取FactoryBean本身。所以需要考虑各种情况,拿到真是的bean名称。
2、从缓存中获取实例(如果已经调用过getBean)
@Override
@Nullable
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
如果第一次调用getBean初始化完成后,则会将实例化的Bean放入DefaultSingletonBeanRegistry的singletonObjects容器中;为了解决单利循环依赖的问题,则在依赖注入时,会提前将未完成的Bean提前放入earlySingletonObjects容器中。创建Bean的工厂与Bean名称的关系存储在singletonFactories容器中。
1、先直接先看是否初始化完成,如果没有拿到,则判断是否正在创建中。
2、如果是则从earlySingletonObjects中进行获取。并且当前allowEarlyReference参数为true,则如果正在依赖注入创建中,直接从工厂中获取
3、如果工厂已经存在,则直接getBean调用工厂的getBean方法,并且提前暴露放到earlySingletonObjects中。
来源:CSDN
作者:it_lihongmin
链接:https://blog.csdn.net/it_lihongmin/article/details/103497439