Spring源码剖析-单利Bean的实例化(六)

本文详细分析了Spring框架中单例Bean的实例化过程,包括从获取Bean定义到判断是否需要立即实例化,再到FactoryBean和普通Bean的区别处理,最后调用`getBean`方法进行Bean的实例化。文章还提到了Bean的初始化接口`SmartInitializingSingleton`以及在实例化过程中处理循环依赖的问题。此外,文章通过代码示例展示了Bean实例化的关键步骤,并附带了流程图辅助理解。
摘要由CSDN通过智能技术生成

@Override

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);

// Trigger initialization of all non-lazy singleton beans…

for (String beanName : beanNames) {

//获取Bean的BeanDefinition 定义对象

RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

//如果不是抽象类,如果是单利,如果lazyInit为false,触发实例化逻辑

if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {

//判断是否是FactoryBean

if (isFactoryBean(beanName)) {

//调用 getBean 方法得到FactoryBean工厂类实例。

//【重要】getBean方法是实例化Bean的核心,后面我们要重点分析这个方法

Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);

//如果是FactoryBean

if (bean instanceof FactoryBean) {

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方法进行Bean的实例化

getBean(beanName);

}

}

}

else {

//【重要】 如果是普通的单利Bean,就调用getBean方法进行Bean的实例化

getBean(beanName);

}

}

}

// Trigger post-initialization callback for all applicable beans…

// 触发所有的Bean的生命周期方法的 init初始化方法.

for (String beanName : beanNames) {

//获取到单利Bean的实例

Object singletonInstance = getSingleton(beanName);

//判断Bean有没有实现 SmartInitializingSingleton接口,SmartInitializingSingleton是针对单利Bean的初始化接口

if (singletonInstance instanceof SmartInitializingSingleton) {

SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;

if (System.getSecurityManager() != null) {

AccessController.doPrivileged((PrivilegedAction) () -> {

smartSingleton.afterSingletonsInstantiated();

return null;

}, getAccessControlContext());

}

else {

//触发afterSingletonsInstantiated方法的调用

smartSingleton.afterSingletonsInstantiated();

}

}

}

}

该方法中先是获取到IOC容器注册的所有的Bean的名字,然后循环拿到每个Bean的BeanDefinition定义对象,然后做了三个判断:不能是抽象,必须是单利,必须是急切初始化, 如果满足条件再看是普通的Bean还是FactoryBean,最终都会调用 getBean(beanName); 方法,该方法调用 AbstractBeanFactory#doGetBean 该方法创建Bean。

创建好Bean之后,会判断Bean是否实现了 SmartInitializingSingleton 初始化接口,这个是针对单利Bean的初始化接口,然后调用afterSingletonsInstantiated进行Bean的初始化。

Bean实例化流程图

========================================================================

先上一个流程图,待会儿你可以根据这个图来看代码。

在这里插入图片描述

AbstractBeanFactory#doGetBean

===========================================================================================

protected T doGetBean(

String name, @Nullable Class requiredType, @Nullable O

  • 8
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值