Bean创建 - doCreateBean
Bean 创建主线 doCreateBean 源码分析
一个 getBean("xxx") 背后, Spring 要回答三个问题: 用哪个构造器造对象、依赖从哪来、初始化时给用户和框架留哪些插手的机会。
答案全在 doGetBean -> createBean -> doCreateBean 这条主线里: 实例化、属性填充、初始化三段拆开, 每段之间都埋了 BeanPostProcessor 扩展点, AOP 代理就是靠其中最后一个扩展点悄悄换掉了你的 bean。
// 基于本地 Spring 仓 (v5.3.39), spring-beans, AbstractBeanFactory。
// getBean 只是门面, 一行转发给 doGetBean。
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
// 真正的查找/创建入口。外层管缓存与作用域策略, 创建本身丢给 createBean 回调
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
String beanName = transformedBeanName(name); // 去掉 FactoryBean 的 & 前缀、解析别名, 得到规范名
Object beanInstance;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName); // 先查单例缓存, 命中就不用创建了
if (sharedInstance != null && args == null) {
// ... 日志省略
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null); // 处理 FactoryBean: 要的是工厂本身还是工厂造的产品
}
else {
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName); // prototype 没有缓存兜底, 创建中又被要 -> 直接判死
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// ... 本工厂没这个定义, 递归委托父工厂, 省略
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName); // 标记"真的要创建了", 顺带让缓存的合并定义失效重算
}
// ...
try {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // 父子 BeanDefinition 合并成 RootBeanDefinition, 后面全用它
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// ... depends-on 成环检测省略
registerDependentBean(dep, beanName);
try {
getBean(dep); // @DependsOn 声明的 bean 先创建, 只管顺序不管注入
}
catch (NoSuchBeanDefinitionException ex) {
// ...
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> { // 加锁 + 标记"创建中" + 回调创建, 成品放一级缓存
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// ... 失败要清掉可能提前暴露出去的半成品
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName); // ThreadLocal 记录创建中, 支撑上面的 prototype 循环检测
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// ... request/session 等自定义 Scope: scope.get(beanName, () -> createBean(...)), 省略
}
}
catch (BeansException ex) {
// ...
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
// ...
}
return adaptBeanInstance(name, beanInstance, requiredType); // 类型不符先尝试转换, 转不动抛 BeanNotOfRequiredTypeException
}// 基于本地 Spring 仓 (v5.3.39), spring-beans, AbstractAutowireCapableBeanFactory。
// createBean: doCreateBean 之前的最后一道关卡, 关键是短路点 resolveBeforeInstantiation
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// ...
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = resolveBeanClass(mbd, beanName); // 确保 Class 真的加载好了 (类名字符串 -> Class 对象)
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd); // 动态解析出的 Class 不能写回共享的合并定义, 拷一份
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
// ... lookup-method / replaced-method 校验, 省略
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse); // InstantiationAwareBPP 短路点: 返回非 null 就直接当成品, 整个 doCreateBean 不走
if (bean != null) {
return bean;
}
// ... 异常包装省略
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
// ...
return beanInstance;
}
// 创建的真正骨架: 实例化 -> (提前暴露) -> 属性填充 -> 初始化
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); // FactoryBean 类型推断阶段可能已经建过实例, 别浪费
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args); // 第一段: 选构造器并 new 出裸对象
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
// ... applyMergedBeanDefinitionPostProcessors: @Autowired/@Resource 的注入点元数据在这里被扫描缓存
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// ...
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); // 把早期引用工厂挂进三级缓存, 专为单例循环依赖服务, 细节归三级缓存那篇
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper); // 第二段: 属性注入
exposedObject = initializeBean(beanName, exposedObject, mbd); // 第三段: 初始化, 返回值可能已被换成代理
}
catch (Throwable ex) {
// ... 统一包装成 BeanCreationException, 省略
}
if (earlySingletonExposure) {
// ... 校验早期引用与最终对象是否一致, 不一致且已被注入出去则报错, 省略
}
// Register bean as disposable.
// ... registerDisposableBeanIfNecessary: 有销毁回调的单例登记到 disposableBeans, 容器关闭时逐个调用
return exposedObject;
}// 基于本地 Spring 仓 (v5.3.39), spring-beans, AbstractAutowireCapableBeanFactory。
// 三段各自的实现。先看第一段: 构造器怎么选
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// ... class 非 public 且不允许访问则抛异常, 省略
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName); // 编程式注册时给的 Supplier 优先级最高, 完全绕开反射
}
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args); // @Bean 方法走这条路: 反射调配置类的工厂方法
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) { // 选过一次就缓存, prototype 第二次创建不再重复推断
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); // 问 SmartInstantiationAwareBPP; @Autowired 构造器就是在这被 AutowiredAnnotationBPP 挑出来的
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args); // 带参构造: 逐个解析参数(参数本身也是 getBean), 再按匹配度打分选定
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors(); // Kotlin 主构造器 / 唯一有参构造器这类"首选"
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd); // 兜底: 无参构造。有 lookup-method 时用 CGLIB 子类, 否则纯反射
}
// 第二段: 属性注入。注解注入的真正执行者是 InstantiationAwareBeanPostProcessor
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// ... bw == null 的兜底省略
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return; // 任何一个 BPP 说 false, 整个属性填充直接跳过
}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// ... XML 时代的 byName/byType 自动装配, 注解驱动的项目基本走不到, 省略
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// ...
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
// ↑ @Autowired/@Value 由 AutowiredAnnotationBPP、@Resource 由 CommonAnnotationBPP 在这一行反射写进字段
// ... pvsToUse == null 时兼容旧接口 postProcessPropertyValues 的回退, 省略
pvs = pvsToUse;
}
}
// ... 依赖检查省略
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs); // XML <property> 声明的值走 setter 写入
}
}
// 第三段: 初始化。固定四步: Aware -> BPP 前置 -> init 方法 -> BPP 后置
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
// ... SecurityManager 分支(已过时), 省略
}
else {
invokeAwareMethods(beanName, bean); // 1. 三个工厂级 Aware 硬编码回调
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
// ↑ 2. @PostConstruct、ApplicationContextAware 等其余 Aware 都在这层被各自的 BPP 处理
}
try {
invokeInitMethods(beanName, wrappedBean, mbd); // 3. afterPropertiesSet + 自定义 init-method
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
// ↑ 4. AOP 入口: AbstractAutoProxyCreator 的后置处理在这里把 bean 换成代理对象
}
return wrappedBean; // 返回的可能已经不是入参那个 bean 了
}
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
// ... 日志与 SecurityManager 分支省略
((InitializingBean) bean).afterPropertiesSet(); // 接口回调优先于自定义 init-method
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && // init-method 恰好叫 afterPropertiesSet 时防止调两次
!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd); // 反射调自定义 init-method
}
}
}
// BPP 链的执行规则: 上一个的输出是下一个的输入, 返回 null 即熔断
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result; // 返回 null 表示"到此为止", 用之前的结果, 后面的 BPP 不再执行
}
result = current;
}
return result;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName); // 代理替换发生的地方: 传进去原始对象, 拿回来可能是代理
if (current == null) {
return result;
}
result = current;
}
return result;
}原理串讲
以单例 userService 第一次被获取为例走一遍。getBean 转发到 doGetBean, 先 transformedBeanName 拿规范名, 再 getSingleton 查缓存, 没命中; 合并出 RootBeanDefinition, 处理完 depends-on 后进入单例分支, 调用带 ObjectFactory 参数的 getSingleton。
这个重载做的是纯粹的单例管理: 加锁、把名字塞进”创建中”集合、回调 createBean、成品入一级缓存。
也就是说 单例语义和创建逻辑是两层分开的: DefaultSingletonBeanRegistry 只管”同名只造一次”, 怎么造它完全不知道; createBean 只管造, 造几次它不关心。
这就是 getBean/doGetBean、createBean/doCreateBean 这种成对命名的含义, 外层方法做检查、缓存、异常包装等通用杂务, do 前缀的方法做实事, 两边职责都不被污染。
createBean 里先把 Class 解析落地, 然后是第一个容易被忽略的点: resolveBeforeInstantiation。
它给 InstantiationAwareBeanPostProcessor 一个在 实例化之前 整体接管的机会, 返回非 null 就直接短路, doCreateBean 一行都不执行。
为什么要留这个口子? 因为有些”bean”根本不需要真实目标对象, 比如给远程接口生成的存根、或对目标类完全代理的场景, 让框架跳过反射实例化直接交货, 比造一个用不上的对象再包装省得多。
平时项目里这个短路点几乎不触发, 但它解释了为什么 AOP 的 AbstractAutoProxyCreator 要同时实现前后两类扩展点。
进入 doCreateBean, 三段式开始。
第一段 createBeanInstance 本质是一台构造器仲裁机, 优先级链条: Supplier > 工厂方法(@Bean) > 缓存的已解析构造器 > BPP 推荐的构造器(@Autowired 构造器由 AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors 挑出) > 首选构造器 > 无参构造兜底。
注意连”选构造器”这件事都问 BeanPostProcessor, Spring 自己不认识 @Autowired, 注解语义全部由 BPP 插件式提供, 这是整个 IoC 内核能保持和注解体系解耦的原因。
选完还会把结果写进 mbd.resolvedConstructorOrFactoryMethod 缓存, prototype 反复创建时不再重复做参数匹配打分。
实例化和属性填充之间, addSingletonFactory 把早期引用工厂挂进三级缓存(循环依赖专用, 本篇不展开)。
然后第二段 populateBean: 真正干活的还是 BPP, postProcessProperties 这一行里, AutowiredAnnotationBeanPostProcessor 按之前扫描缓存好的注入点元数据, 对每个 @Autowired 字段调 resolveDependency 找依赖(依赖不存在时又递归回 doGetBean), 反射写入。
XML 的 <property> 值则最后走 applyPropertyValues 通过 setter 灌入。
第三段 initializeBean, 四步固定顺序:
代码块收起展开
`invokeAwareMethods` 硬编码回调三个工厂级 Aware;
BPP 前置(`@PostConstruct` 其实是 `CommonAnnotationBeanPostProcessor` 在这一步调的, 不在 init 方法那步);
`invokeInitMethods` 调 `afterPropertiesSet` 和自定义 init-method;最后 BPP 后置, AbstractAutoProxyCreator.postProcessAfterInitialization 判断该 bean 是否匹配切面, 匹配就返回代理对象, wrappedBean 从此指向代理。
为什么代理偏偏放在最后一步? 因为代理必须包住一个 完全体: 属性已注入、init 方法已跑完, 这样代理转发到目标对象时目标才是可用状态; 若在实例化阶段就代理, 后续的字段注入和初始化会落在代理壳上而不是目标上, 语义全乱。
这也解释了一个高频坑: init 方法执行时 this 还是原始对象, 里面的自调用永远不走代理, 事务/缓存注解在自调用链上失效, 根源就在于代理是初始化 之后 才出现的。
最后 doCreateBean 返回 exposedObject(可能是代理), 经 getSingleton 存入一级缓存, doGetBean 再过一遍 getObjectForBeanInstance(FactoryBean 场景)和 adaptBeanInstance(类型转换), 交货。
设计取舍
- 三段式(实例化/填充/初始化)拆开而不是一个构造器搞定一切, 代价是流程长, 换来的是每段之间都能插 BPP 扩展点, AOP、注解注入、
@PostConstruct全是插件, 内核零感知。 - 注解构造器注入的解析由 BPP 提供而非内核硬编码, 所以没有 spring-context 里的注解 BPP 时, 裸
DefaultListableBeanFactory根本不认识@Autowired。 - BPP 链”返回 null 即熔断”是契约不是异常: 自定义 BPP 手滑返回 null 会静默吞掉后面所有处理器(包括 AOP 代理), bean 看起来正常但切面全丢。
- 初始化回调的真实顺序是
@PostConstruct->afterPropertiesSet->init-method, 因为第一个在 BPP 前置阶段执行, 后两个才在invokeInitMethods里。 - 代理在 BPP 后置生成, 意味着 init 方法内和自调用场景拿到的都是原始对象, 事务注解在这些路径上不生效。