获取bean
Spring 获取 Bean 完整流程源码解析:从 getBean 到 Bean 就绪
Spring 容器获取 Bean 的核心入口是 getBean() 方法,但其底层逻辑完全封装在 doGetBean() 中 —— 这是 Spring IOC 容器实现 “Bean 查找、创建、依赖注入、初始化” 的核心方法。从 “入口触发→Bean 名称处理→缓存查找(三级缓存)→循环依赖处理→不同作用域 Bean 创建→属性注入与初始化” 六个维度,逐行拆解获取 Bean 的全流程。
核心入口:getBean() 与 doGetBean()
getBean() 是用户调用的入口方法,但其仅做简单转发,真正的逻辑全部在 doGetBean() 中实现。这一设计遵循 “职责单一” 原则 ——getBean() 暴露接口,doGetBean() 封装复杂逻辑。
1. 入口方法调用链
// 1. 用户调用:从容器获取 Bean(示例)
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
Car car = (Car) context.getBean("car"); // 入口1:调用 ApplicationContext 的 getBean()
// 2. ApplicationContext 继承 BeanFactory,最终委托给 AbstractBeanFactory 的 getBean()
// AbstractBeanFactory#getBean(String name)
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false); // 入口2:转发到 doGetBean()
}
2. doGetBean():获取 Bean 的 “总控制器”
doGetBean() 是整个流程的核心,代码虽长,但逻辑清晰,可拆解为 8 个关键步骤,每个步骤对应特定职责:
protected <T> T doGetBean(
final String name, // 用户传入的 Bean 名称(可能是别名/FactoryBean)
final Class<T> requiredType, // 期望的 Bean 类型(用于类型转换)
final Object[] args, // 构造方法参数(创建 Bean 时用)
boolean typeCheckOnly // 是否仅做类型检查(不创建 Bean)
) throws BeansException {
// ========================= 步骤1:处理 Bean 名称,得到真实 beanName =========================
final String beanName = transformedBeanName(name);
Object bean;
// ========================= 步骤2:从缓存查找单例 Bean(解决循环依赖) =========================
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 处理 FactoryBean:返回 FactoryBean 生成的目标对象(而非 FactoryBean 本身)
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// ========================= 步骤3:缓存未命中,处理非单例/未创建的单例 =========================
else {
// 3.1 原型 Bean 循环依赖检查(原型无法解决循环依赖,直接报错)
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 3.2 父容器查找(若当前容器无该 BeanDefinition,委托父容器查找)
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name); // 恢复原始名称(如 &前缀)
return (T) parentBeanFactory.getBean(nameToLookup, args); // 父容器递归查找
}
// 3.3 标记 Bean 为“已创建”(避免重复创建)
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 3.4 合并 BeanDefinition(处理父子 Bean 继承,如 parent 属性)
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args); // 校验 BeanDefinition
// 3.5 初始化当前 Bean 依赖的其他 Bean(dependsOn 配置)
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 检查循环依赖(如 A depends-on B,B depends-on A)
if (isDependent(beanName, dep)) {
throw new BeanCreationException("循环依赖:" + beanName + " ↔ " + dep);
}
registerDependentBean(dep, beanName); // 注册依赖关系
getBean(dep); // 递归初始化被依赖的 Bean
}
}
// ========================= 步骤4:根据作用域创建 Bean =========================
// 4.1 单例 Bean(核心:缓存+全局唯一)
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args); // 真正创建单例 Bean
} catch (BeansException ex) {
destroySingleton(beanName); // 创建失败,清理缓存
throw ex;
}
}
});
// 处理 FactoryBean:返回目标对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 4.2 原型 Bean(每次 getBean() 都创建新实例)
else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName); // 标记原型 Bean 开始创建
prototypeInstance = createBean(beanName, mbd, args); // 创建新实例
} finally {
afterPrototypeCreation(beanName); // 标记原型 Bean 创建完成
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 4.3 其他作用域(如 request、session,需自定义 Scope 实现)
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("未注册作用域:" + scopeName);
}
try {
// 委托 Scope 接口创建 Bean(如 request 作用域绑定到当前请求)
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException ex) {
throw new BeanCreationException("作用域 " + scopeName + " 未激活");
}
}
} catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName); // 创建失败,清理资源
throw ex;
}
}
// ========================= 步骤5:类型检查与转换 =========================
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
try {
// 类型转换(如 String → Integer,依赖 ConversionService)
return getTypeConverter().convertIfNecessary(bean, requiredType);
} catch (TypeMismatchException ex) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
关键步骤深度拆解
步骤 1:transformedBeanName()—— 处理 Bean 名称
用户传入的 name 可能是别名、FactoryBean 名称(带 & 前缀),需转换为 “真实 beanName”:
// AbstractBeanFactory#transformedBeanName
protected String transformedBeanName(String name) {
// 1. 移除 FactoryBean 前缀 &(如 &userFactory → userFactory)
String beanName = BeanFactoryUtils.transformedBeanName(name);
// 2. 解析别名(从 aliasMap 中获取原始 beanName,如 "carAlias" → "car")
if (this.aliasMap.containsKey(beanName)) {
String canonicalName;
do {
canonicalName = this.aliasMap.get(beanName);
beanName = canonicalName;
} while (this.aliasMap.containsKey(beanName));
}
return beanName;
}
- FactoryBean 前缀 &:
&userFactory表示获取UserFactory本身,而非其getObject()生成的User对象; - 别名解析:Spring 允许通过
<alias name="car" alias="carAlias"/>配置别名,此处需递归解析到原始 beanName。
步骤 2:getSingleton()—— 三级缓存与循环依赖解决
Spring 用三级缓存存储单例 Bean 的不同状态,核心目标是解决单例 Bean 的循环依赖(如 A 依赖 B,B 依赖 A),原型 Bean 因无缓存无法解决循环依赖。
(1)三级缓存定义
// AbstractBeanFactory 的父类 DefaultSingletonBeanRegistry 中定义
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); // 一级缓存:完整单例 Bean(id→实例)
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); // 三级缓存:Bean 工厂(id→ObjectFactory)
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); // 二级缓存:早期单例 Bean(未完成属性注入,id→实例)
(2)getSingleton() 缓存查找逻辑
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1. 先查一级缓存:是否存在完整的单例 Bean
Object singletonObject = this.singletonObjects.get(beanName);
// 2. 一级缓存无,且当前 Bean 正在创建(可能存在循环依赖)
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) { // 同步锁:避免并发问题
// 3. 查二级缓存:是否存在早期 Bean(未完成属性注入)
singletonObject = this.earlySingletonObjects.get(beanName);
// 4. 二级缓存无,且允许早期引用(循环依赖场景)
if (singletonObject == null && allowEarlyReference) {
// 5. 查三级缓存:获取 Bean 工厂(ObjectFactory)
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 6. 调用 ObjectFactory.getObject():生成早期 Bean(未注入属性)
singletonObject = singletonFactory.getObject();
// 7. 早期 Bean 移到二级缓存,删除三级缓存(避免重复生成)
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
(3)三级缓存解决循环依赖示例(A 依赖 B,B 依赖 A)
- 创建 A:调用
doCreateBean(A),实例化 A 后,将ObjectFactory(A)放入三级缓存; - A 注入 B:A 需注入 B,调用
getBean(B); - 创建 B:调用
doCreateBean(B),实例化 B 后,将ObjectFactory(B)放入三级缓存; - B 注入 A:B 需注入 A,调用
getBean(A); - 查找 A:从三级缓存获取
ObjectFactory(A),生成早期 A(未注入属性),放入二级缓存; - B 初始化完成:B 注入早期 A 后,完成初始化,放入一级缓存;
- A 注入 B:A 从一级缓存获取完整 B,完成属性注入,放入一级缓存。
核心结论:三级缓存通过 “提前暴露未完成初始化的 Bean”,打破了单例 Bean 的循环依赖死锁。
步骤 3:getObjectForBeanInstance()—— 处理 FactoryBean
Spring 中 Bean 分为普通 Bean 和 FactoryBean:
- 普通 Bean:直接返回实例;
- FactoryBean:返回其
getObject()生成的目标对象(需特殊处理)。
源码逻辑拆解
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
// 1. 若名称带 & 但实例不是 FactoryBean → 报错(非法使用 & 前缀)
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
// 2. 普通 Bean 或用户明确获取 FactoryBean 本身(带 &)→ 直接返回
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
// 3. 处理 FactoryBean:生成目标对象
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName); // 查 FactoryBean 缓存
}
if (object == null) {
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// 合并 BeanDefinition(处理父子继承)
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
// 判断是否为 Spring 内部合成的 FactoryBean(如 AOP 代理)
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 核心:调用 FactoryBean.getObject() 生成目标对象
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
关键细节
- FactoryBean 缓存:单例 FactoryBean 生成的目标对象会存入
factoryBeanObjectCache,避免重复调用getObject(); - & 前缀作用:
getBean("&userFactory")返回UserFactory本身,getBean("userFactory")返回userFactory.getObject()生成的User对象。
步骤 4:createBean()→doCreateBean()——Bean 实例化与初始化
当缓存无 Bean 且需新建时,createBean() 是入口,实际逻辑在 doCreateBean() 中,包含 “实例化→属性注入→初始化” 三大核心环节。
(1)doCreateBean() 核心流程
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// ========================= 环节1:实例化 Bean(创建空对象) =========================
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); // 清理 FactoryBean 缓存
}
if (instanceWrapper == null) {
// 核心:通过构造器/工厂方法创建 Bean 实例(未注入属性)
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance(); // 原始 Bean 实例
Class<?> beanType = instanceWrapper.getWrappedClass();
mbd.resolvedTargetType = beanType;
// ========================= 环节2:处理 Merged BeanDefinition(注解解析) =========================
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
// 核心:处理 @Autowired、@Value 等注解(AutowiredAnnotationBeanPostProcessor 生效)
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
// ========================= 环节3:提前暴露 Bean(解决循环依赖) =========================
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 把 Bean 工厂放入三级缓存(循环依赖时,其他 Bean 可通过工厂获取早期实例)
addSingletonFactory(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
// 对早期 Bean 应用后置处理(如 AOP 代理)
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// ========================= 环节4:属性注入(填充依赖) =========================
Object exposedObject = bean;
try {
// 核心:注入属性(处理 <property>、@Autowired、自动注入 byName/byType)
populateBean(beanName, mbd, instanceWrapper);
// ========================= 环节5:初始化 Bean(增强与回调) =========================
if (exposedObject != null) {
// 核心:执行 Aware 接口、BeanPostProcessor、init-method
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
} catch (Throwable ex) {
throw new BeanCreationException("Bean 初始化失败", ex);
}
// ========================= 环节6:注册销毁方法(如 destroy-method) =========================
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException("销毁方法配置错误", ex);
}
return exposedObject;
}
(2)关键子环节详解
① createBeanInstance():实例化 Bean
通过以下方式创建空对象(未注入属性):
- 构造器实例化:默认无参构造器,或根据
constructor-arg匹配有参构造器; - 工厂方法实例化:静态工厂(
factory-method)或实例工厂(factory-bean + factory-method)。
② populateBean():属性注入
核心是 “将依赖的 Bean 或简单值注入到当前 Bean 的属性中”,支持三种注入方式:
- XML 显式配置:
<property name="userDao" ref="userDao"/>; - 自动注入:
autowire="byName"(按属性名匹配 Bean)或autowire="byType"(按属性类型匹配 Bean); - 注解注入:
@Autowired(由AutowiredAnnotationBeanPostProcessor处理)、@Value(解析 SpEL 表达式)。
源码关键逻辑:
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// 1. 处理 InstantiationAwareBeanPostProcessor(如 @Autowired 注入前的准备)
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return; // 终止注入(如自定义注入逻辑已处理)
}
}
}
}
// 2. 自动注入(byName/byType)
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(mbd.getPropertyValues());
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs); // 按属性名匹配 Bean
}
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs); // 按属性类型匹配 Bean
}
mbd.setPropertyValues(newPvs);
}
// 3. 应用属性值到 Bean(最终调用 setXxx() 方法注入)
applyPropertyValues(beanName, mbd, bw, mbd.getPropertyValues());
}
③ initializeBean():初始化 Bean
Bean 实例化并注入属性后,执行初始化逻辑,按以下顺序执行:
- Aware 接口回调:注入容器服务(如
BeanNameAware、ApplicationContextAware); - BeanPostProcessor 前置处理:
postProcessBeforeInitialization()(如@PostConstruct注解执行); - 初始化方法:
InitializingBean.afterPropertiesSet()→ XML/@Bean配置的init-method; - BeanPostProcessor 后置处理:
postProcessAfterInitialization()(AOP 代理生成在此处)。
源码逻辑:
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
// 1. Aware 接口回调(如 BeanNameAware.setBeanName())
invokeAwareMethods(beanName, bean);
// 2. BeanPostProcessor 前置处理
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 3. 执行初始化方法
try {
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException("初始化方法执行失败", ex);
}
// 4. BeanPostProcessor 后置处理(AOP 代理生成)
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
不同作用域 Bean 的创建差异
Spring 支持多种 Bean 作用域,核心差异在于 “实例数量” 和 “生命周期管理”,doGetBean() 中针对不同作用域有不同处理逻辑:
| 作用域 | 实例数量 | 生命周期管理 | 创建逻辑关键点 |
|---|---|---|---|
| singleton(单例) | 容器内唯一 | 容器启动时创建(非懒加载),容器关闭时销毁 | 存入 singletonObjects 缓存,仅创建一次 |
| prototype(原型) | 每次 getBean() 新实例 |
实例化后容器不再管理(需手动销毁) | 不缓存,每次调用 createBean() 生成新实例 |
| request | 每个 HTTP 请求新实例 | 请求结束时销毁 | 委托 RequestScope 绑定到当前请求 |
| session | 每个 HTTP Session 新实例 | Session 过期时销毁 | 委托 SessionScope 绑定到当前 Session |
总结:获取 Bean 的完整链路
Spring 获取 Bean 的流程本质是 “先查缓存→再处理依赖→最后创建实例”,可精简为 10 步:
- 调用
getBean(name),转发到doGetBean(); transformedBeanName():解析别名和 FactoryBean 前缀,得到真实 beanName;getSingleton(beanName):从三级缓存查找单例 Bean,存在则返回;- 检查原型循环依赖,存在则报错;
- 若父容器存在且当前容器无该 BeanDefinition,委托父容器查找;
- 处理
dependsOn:递归getBean()初始化被依赖的 Bean; - 根据作用域创建 Bean:
- 单例:调用
getSingleton()传入ObjectFactory,内部调用createBean(); - 原型:直接调用
createBean()生成新实例;
- 单例:调用
- doCreateBean():
createBeanInstance():实例化 Bean(空对象);applyMergedBeanDefinitionPostProcessors():解析@Autowired等注解;- 提前暴露 Bean 到三级缓存(解决循环依赖);
populateBean():属性注入;initializeBean():执行 Aware 回调、BeanPostProcessor、init-method;
getObjectForBeanInstance():若为 FactoryBean,返回其getObject()生成的目标对象;- 类型转换:将 Bean 转换为用户期望的类型,返回给用户