Spring Bean的实例化 - 从源码角度进行全解析
一、引言
在Spring中,一个Bean的“一生”要经历定义解析、实例化、属性填充、初始化、销毁等多个阶段。而我们今天的主角——实例化,是指容器通过反射或工厂方法,为Bean分配内存空间,并创建一个原始对象的过程。
这个过程的宏观起点,通常是从ApplicationContext的refresh()方法开始的。对于非懒加载的单例Bean,实例化的统一入口在finishBeanFactoryInitialization方法中。
1 2 3 4 5 6 7
| protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { beanFactory.preInstantiateSingletons(); }
|
从这里开始,Spring将遍历所有已注册的BeanDefinition,并逐一调用getBean()来触发实例化流程。我们将跟随这条主线,深入每一个细节。
二:从 getBean() 到 createBean()
2.1 doGetBean()
getBean()方法是获取Bean的入口,但其真正的实现逻辑在doGetBean()中。这个方法承担了从缓存获取实例、处理依赖、区分作用域等重要职责。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| protected <T> T doGetBean( String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { String beanName = transformedBeanName(name); Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) { bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); }
BeanFactory parentBeanFactory = getParentBeanFactory();
if (!typeCheckOnly) { markBeanAsCreated(beanName); }
try { RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { registerDependentBean(dep, beanName); getBean(dep); } }
if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { } else { } } catch (BeansException ex) { } } return (T) bean; }
|
在这个漫长的前奏中,最重要的收获是:Spring通过三级缓存尝试获取提前暴露的Bean(解决循环依赖),并最终通过回调的方式,触发了createBean()方法。
1.2 getSingleton()
在doGetBean()开始时调用的getSingleton(beanName),对应的是DefaultSingletonBeanRegistry中的三级缓存机制。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 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)) { 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; }
|
这个三级缓存的巧妙设计,是Spring解决循环依赖的基石。在实例化阶段,我们只需记住:当一个Bean正在创建时,它的“早期引用”可能会通过三级缓存暴露给其他依赖它的Bean
三、createBean()
当缓存中不存在Bean,且作用域为单例时,getSingleton(String, ObjectFactory) 方法会调用传入的 ObjectFactory 的 getObject() 方法,也就是下面的 createBean() 方法。
createBean()是整个实例化流程的总指挥,它位于AbstractAutowireCapableBeanFactory中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| @Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isTraceEnabled()) { logger.trace("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); }
try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(...); }
try { Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(...); }
try { Object beanInstance = doCreateBean(beanName, mbdToUse, args); return beanInstance; } catch (Throwable ex) { } }
|
3.1 前置拦截:resolveBeforeInstantiation()
这个方法是一个极其重要的扩展点。它会调用实现了InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation()方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }
|
这个机制的意义在于:允许用户在Bean被实例化之前,自己生成一个对象返回。典型的应用场景包括:AOP动态代理、模拟对象等。如果这个钩子返回了一个对象,那么后续的doCreateBean()将不会执行,Bean的“实例化”就此打住
四:doCreateBean() —— 实例化核心流程
doCreateBean()是Spring中最复杂、最重要的方法之一。它囊括了实例化、属性填充、初始化等全生命周期,但今天我们只聚焦于实例化这一步。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); }
|
可以看到,实例化的核心实现委托给了 createBeanInstance() 方法。
4.1 createBeanInstance():选择合适的实例化策略
这个方法的目标很明确:给我一个 RootBeanDefinition,我还你一个 BeanWrapper(包装了原始对象的反射工具类)。Spring提供了多种实例化方式,按优先级排序如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { Class<?> beanClass = resolveBeanClass(mbd, beanName);
Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); }
if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); }
boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); } else { return instantiateBean(beanName, mbd); } }
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); }
return instantiateBean(beanName, mbd); }
|
这个方法的逻辑非常清晰,像是一个路由器,根据不同的配置将请求分发给不同的处理器
4.1.1 方式一:Supplier 创建
Spring 5.0 引入,允许通过编程方式提供一个 Supplier 来创建实例,非常灵活。
4.1.2 方式二:工厂方法
对应配置中的 factory-method。如果是静态工厂方法,直接调用;如果是实例工厂方法,则需要先实例化工厂Bean。
4.1.3 方式五:构造器推断 —— determineConstructorsFromBeanPostProcessors()
这是注解驱动开发中(如 @Autowired 标注在构造器上)最常用的方式。它会调用 SmartInstantiationAwareBeanPostProcessor 的 determineCandidateConstructors() 方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(Class<?> beanClass, String beanName) throws BeansException { if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName); if (ctors != null) { return ctors; } } } } return null; }
|
以 AutowiredAnnotationBeanPostProcessor 为例,它会扫描类中的构造器,如果找到唯一的一个有参构造器,或者某个构造器被 @Autowired 标注,则将其作为候选返回 。
4.2 无参实例化:instantiateBean()
如果确定使用默认无参构造器,流程会走到这里。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) { try { Object beanInstance; if (System.getSecurityManager() != null) { } else { beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this); } BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; } catch (Throwable ex) { throw new BeanCreationException(...); } }
|
4.2.1 SimpleInstantiationStrategy.instantiate()
真正的反射调用在这里发生。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { if (!bd.hasMethodOverrides()) { Constructor<?> constructorToUse; synchronized (bd.constructorArgumentLock) { constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod; if (constructorToUse == null) { final Class<?> clazz = bd.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); } try { constructorToUse = clazz.getDeclaredConstructor(); bd.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Exception ex) { } } } return BeanUtils.instantiateClass(constructorToUse); } else { return instantiateWithMethodInjection(bd, beanName, owner); } }
|
这里有个重要细节:如果 Bean 中配置了 <lookup-method> 或 <replaced-method>,Spring 不能直接使用反射创建原始对象,而是必须通过 CGLIB 动态生成一个子类,并在子类中实现方法的覆写逻辑
4.3 有参实例化:autowireConstructor()
这是最复杂的分支,涉及到构造器的匹配、参数值的解析和类型转换。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) { BeanWrapperImpl bw = new BeanWrapperImpl(); this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null; ArgumentsHolder argsHolderToUse = null; Object[] argsToUse = null;
if (explicitArgs != null) { argsToUse = explicitArgs; } else { }
if (constructorToUse == null) { Constructor<?>[] candidates = chosenCtors; if (candidates == null) { Class<?> beanClass = mbd.getBeanClass(); candidates = (mbd.isNonPublicAccessAllowed() ? beanClass.getDeclaredConstructors() : beanClass.getConstructors()); }
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE; Set<Constructor<?>> ambiguousConstructors = null;
for (Constructor<?> candidate : candidates) { Class<?>[] paramTypes = candidate.getParameterTypes();
if (constructorToUse != null && argsToUse.length > paramTypes.length) { break; } if (paramTypes.length < minNrOfArgs) { continue; }
ArgumentsHolder argsHolder; if (resolvedValues != null) { try { String autowiredBeanName = null; Object value = null;
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, methodHolder); } catch (BeansException ex) { throw ex; } } else { argsHolder = new ArgumentsHolder(paramTypes.length); }
int typeDiffWeight = argsHolder.getTypeDifferenceWeight(paramTypes); if (typeDiffWeight < minTypeDiffWeight) { constructorToUse = candidate; argsHolderToUse = argsHolder; argsToUse = argsHolder.arguments; minTypeDiffWeight = typeDiffWeight; ambiguousConstructors = null; } else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) { if (ambiguousConstructors == null) { ambiguousConstructors = new LinkedHashSet<>(); ambiguousConstructors.add(constructorToUse); } ambiguousConstructors.add(candidate); } }
if (constructorToUse == null) { throw new BeanCreationException(...); } else if (ambiguousConstructors != null) { throw new BeanCreationException(...); }
if (explicitArgs == null && argsHolderToUse != null) { mbd.resolvedConstructorOrFactoryMethod = constructorToUse; mbd.constructorArgumentsResolved = true; mbd.constructorArgumentValues = argsHolderToUse; } }
try { Object beanInstance = this.beanFactory.getInstantiationStrategy().instantiate( mbd, beanName, this.beanFactory, constructorToUse, argsToUse); bw.setBeanInstance(beanInstance); return bw; } catch (Throwable ex) { throw new BeanCreationException(...); } }
|
整个autowireConstructor过程可以概括为:穷举 -> 解析参数 -> 计算权重 -> 选出最优 -> 反射调用。这也是Spring为什么能智能地根据你提供的参数自动匹配合适构造器的原因 。
4.3.1 参数解析的深度:createArgumentArray()
在解析参数值时,如果参数是引用类型(如另一个Bean),Spring会递归调用getBean()去创建或获取依赖的Bean。这正是依赖注入在实例化阶段的体现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| private ArgumentsHolder createArgumentArray(...) { for (int i = 0; i < paramTypes.length; i++) { ValueHolder valueHolder = resolvedValues.getArgumentValue(i, paramTypes[i], ...); if (valueHolder == null) { autowiredBeanName = resolveAutowiredArgument(paramTypes[i], ...); } else { convertedValue = beanFactory.convertIfNecessary(valueHolder.getValue(), paramTypes[i]); } } }
|
五、实例化后—— 早期暴露与循环依赖
对象被createBeanInstance()成功创建出来后,在doCreateBean()中,还有一步与实例化密切相关的重要操作:提前暴露早期引用。
1 2 3 4 5 6 7 8 9 10 11
| boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); }
|
getEarlyBeanReference() 方法会调用 SmartInstantiationAwareBeanPostProcessor 的 getEarlyBeanReference(),这是解决 AOP 代理与循环依赖冲突的关键。如果 Bean 需要被代理,这里返回的就是代理对象的早期引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); } } } return exposedObject; }
|
至此,一个原始的、可能尚未填充属性的 Bean 实例已经躺在三级缓存中,随时准备为它的“兄弟们”解决循环依赖问题。
六、实例化策略——InstantiationStrategy
回顾整个实例化过程,无论是无参构造器、有参构造器还是工厂方法,最终创建对象的操作都委托给了InstantiationStrategy。这是一个策略接口,有两个主要实现:
- **
SimpleInstantiationStrategy**:支持通过反射实例化,不支持方法注入。
- **
CglibSubclassingInstantiationStrategy**(默认使用):继承自SimpleInstantiationStrategy,增加了通过 CGLIB 生成子类来支持方法注入的能力。
当检测到RootBeanDefinition中存在methodOverrides时,策略实现类会这样处理:
1 2 3 4 5 6 7 8 9 10 11
| public Object instantiate(Constructor<?> ctor, Object... args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.beanDefinition.getBeanClass()); enhancer.setCallbackTypes(new Class[]{NoOp.class, LookupOverrideMethodInterceptor.class, ReplaceOverrideMethodInterceptor.class}); return enhancer.create(); }
|
这意味着,如果一个普通的单例 Bean 没有使用方法注入,它仍然是通过反射创建的,性能很高;只有必要时才启用 CGLIB。
七、总结
从getBean()到最终对象的诞生,Spring Bean 的实例化流程是一条设计精密的流水线。我们可以将其核心逻辑概括为以下流程:
- 入口统一:所有实例化始于
getBean(),经过doGetBean()的复杂预处理(处理依赖、作用域、父工厂)。
- 前置拦截:
resolveBeforeInstantiation 提供了在实例化前直接返回代理对象的扩展点。
- 策略路由:
createBeanInstance 根据Supplier、工厂方法、构造器推断、默认无参等条件,选择合适的实例化方式。
- 构造器推断:
autowireConstructor 通过复杂的权重计算和参数解析,智能地选出最佳构造器。
- 反射/CGLIB:最终通过
InstantiationStrategy,利用反射或CGLIB技术,在内存中开辟空间,构建出原始对象。
- 提前暴露:实例化后的原始对象会被包装成
ObjectFactory放入三级缓存,为后续可能的循环依赖做好准备。
这不仅仅是“new一个对象”那么简单。Spring 通过这一系列精巧的设计,将控制反转和依赖注入的理念落到了实处,既保证了灵活性(丰富的扩展点),又兼顾了性能(反射缓存、策略选择)。