前言
上一篇文章中,我们介绍了Spring IoC 的容器初始化过程 - IoC 容器初始化
本篇文章中,我们继续介绍Spring IoC 依赖注入的过程和源码解读。
还是如之前一样,为大家梳理一下步骤流程,以便于大家能在心里有个大概的脉络,更容易读懂源码,更容易抓住重点。
主要内容:
- beanName 解析转换
- 手动注册Bean检测
- 双亲容器检测
- 依赖初始化(递归)
- ★ 创建singleton 实例
- 对象实例化
- 属性装配
- 处理Bean创建之后的各种回调事件
- …
源码解析
上一章最后一节,容器初始化的倒数第二步,finishBeanFactoryInitialization(beanFactory)
实例化所有单例,调用了getBean()
方法来做singleton bean 的实例化操作。这就是Spring IoC 依赖注入的入口。
在开始之前,有一点需要提一下。前面我们是从容器初始化之后进来的,但实际操作中,我们有可能是在程序普通运行情况下,用ApplicationContext.getBean()
去获取容器中bean。不要局限于刚刚的视角中。
现在让我们开始吧。
首先看看getBean()
源码位置:AbstractBeanFactory#getBean(String name)
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
doCreateBean()
deGetBean()
- beanName 解析转换
- 检测 手动注册Bean
- 双亲容器检测
- 依赖初始化(递归)
- 创建Bean
createBean()
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
// 反正就是获取到真正beanName
// 处理两个情况,1. 将别名转化成真的beanName;2. 把FactoryBean的前缀"&"给去了
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 检测已经注册的Bean,保证不重复创建
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 这个方法还是有点逻辑的
// 如果目前获得的sharedInstance 不是FactoryBean,那bean就赋值成sharedInstance,直接返回
// 如果是FactoryBean就返回FactoryBean创建的实例,
// 这个也是FactoryB