AbstractBeanFactory的getBean方法

本文详细剖析了Spring框架中Bean的创建过程,包括AbstractBeanFactory的getBean方法的执行流程,从查找Bean、实例化Bean到初始化Bean的全过程。特别关注了createBean方法中的关键步骤,如Bean实例化、依赖注入及初始化等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AbstractBeanFactory的getBean方法,会调用doGetBean:
1. 调用transformedBeanName获取beanName:transformedBeanName调用canonicalName,参数为BeanFactoryUtils.transformedBeanName(name),BeanFactoryUtils的transformedBeanName方法会去除beanName的工厂前缀;canonicalName方法将name当作别名,找到最原始的name;
2. 调用getSingleton(beanName):获取beanFactory的singletonObjects中已经包含的单例,如果earlySingletonObjects未找到并且isSingletonCurrentlyInCreation,则去获取earlySingletonObjects属性中的单例,如果还未找到 并且allowEarlyReference,则去singletonFactories属性中获取bean;
3. 未找到singleton且参数args为null,如果isPrototypeCurrentlyInCreation,可能存在循环引用,抛BeanCurrentlyInCreationException;
4. getParentBeanFactory不为null且包含当前beanName,调用originalBeanName方法获取工厂bean名称,这个方法调用transformedBeanName后为beanName加上工厂bean的前缀,然后调用parentBeanFactory的getBean方法
5. 如果不是typeCheckOnly,markBeanAsCreated:将beanName加入到beanFactory的alreadyCreated属性中,然后clearMergedBeanDefinition,将beanName从beanFactory的mergedBeanDefinitions属性中移除(正在真正的创建bean,让beanDefinition能够re-merged,防止它的metadata在创建时发生改变。)
6. getMergedLocalBeanDefinition 从parent beanDefinition和子beanDefinition获取合并后的merged RootBeanDefinition;
7. checkMergedBeanDefinition 如果beanDefinition为抽象的则抛出BeanIsAbstractException
8. 获取beanDefinition的dependsOn,然后registerDependentBean,getBean,确保当前bean依赖的bean都能初始化完成;
9. 如果beanDefinition为isSingleton:
(1)getSingleton:从beanFactory的singletonObjects属性中获取单例缓存,如果为空:先调用beforeSingletonCreation,如果beanFactory的inCreationCheckExclusions属性中不包含当前beanName并且向singletonsCurrentlyInCreation属性中添加beanName失败,抛出BeanCurrentlyInCreationException;然后调用singletonFactory的getObject方法,getObject方法调用的是AbstractBeanFactory的createBean方法;然后调用afterSingletonCreation,如果beanFactory的inCreationCheckExclusions属性中不包含当前beanName并且从singletonsCurrentlyInCreation属性中移除beanName失败,抛出IllegalStateException;最后调用addSingleton,将beanName及新建的bean加入到beanFactory的singletonObjects,将beanName加入到registeredSingletons,从singletonFactories和earlySingletonObjects移除beanName。
AbstractBeanFactory的createBean方法执行过程如下:
1)resolveBeanClass获取beanDefinition的beanClass
2)调用RootBeanDefinition的prepareMethodOverrides方法, 验证和准备这个bean定义的method overrides,校验特定名称的方法是否存在,如果不存在标记为not overloaded;
3)resolveBeforeInstantiation(beanName, mbdToUse),使BeanPostProcessors有机会返回proxy实例而不是bean实例,如果这个方法返回的结果不为null就直接返回(返回的bean是BeanPostProcessors处理过的proxy):
如果beanDefinition的beforeInstantiationResolved属性不为false,beanDefinition不为synthetic且hasInstantiationAwareBeanPostProcessors属性为true,则获取beanDefinition的targetType,调用applyBeanPostProcessorsBeforeInstantiation(targetType, beanName)方法,执行所有BeanPostProcessors的postProcessBeforeInstantiation方法,这个方法默认返回不为null,如果返回结果为null,会跳出循环直接返回,后面的BeanPostProcessors将不会被应用;如果applyBeanPostProcessorsBeforeInstantiation返回结果不为null,调用applyBeanPostProcessorsAfterInitialization(bean, beanName)方法,执行所有BeanPostProcessors的postProcessAfterInitialization方法,这个方法默认返回不为null,如果返回结果为null,会跳出循环直接返回,后面的BeanPostProcessors将不会被应用;根据BeanPostProcessors的返回结果是否为null设置BeanDefinitiond的beforeInstantiationResolved属性。
4)doCreateBean,创建bean:
factoryBeanInstanceCache移除beanName返回的结果作为BeanWrapper,
如果为null,调用createBeanInstance得到BeanWrapper:
a)调用resolveBeanClass(mbd, beanName)方法获取beanClass;
b)如果beanClass不为空,不是public,不允许NonPublicAccess,抛BeanCreationException
c)BeanDefinition的FactoryMethodName不为空,调用instantiateUsingFactoryMethod方法,这个方法用工厂方法实例化bean。
d)如果BeanDefinition的resolvedConstructorOrFactoryMethod不为null,resolved设置为true,autowireNecessary设置为BeanDefinition的constructorArgumentsResolved属性;
e)如果resolved为true,autowireNecessary为true,调用autowireConstructor(beanName, mbd, null, null);如果resolved为true,autowireNecessary为false,调用instantiateBean(beanName, mbd)
f)调用determineConstructorsFromBeanPostProcessors方法获取constructors:找到所有的BeanPostProcessor,调用类型为SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法,返回结果不为null就作为constructors返回;
g)如果constructors不为空,或BeanDefinition的AutowireMode为AUTOWIRE_CONSTRUCTOR,或BeanDefinition的constructorArgumentValues不为空,或传入的参数args不为null,调用autowireConstructor(beanName, mbd, ctors, args)生成bean实例返回
h)默认调用instantiateBean(beanName, mbd)使用无参构造函数生成bean实例返回
instantiateBean的执行过程如下:
先调用getInstantiationStrategy().instantiate(mbd, beanName, parent),getInstantiationStrategy()返回beanFactory的instantiationStrategy,类型为CglibSubclassingInstantiationStrategy,
instantiate()方法中,如果BeanDefinition的methodOverride为空,不使用cglib重载类:constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod,如果constructorToUse为null,获取beanDefinition的beanClass的getDeclaredConstructor作为构造函数,如果beanDefinition的beanClass为接口就抛出BeanInstantiationException,返回BeanUtils.instantiateClass(constructorToUse)的结果;如果BeanDefinition的methodOverride不为空,调用instantiateWithMethodInjection方法:返回new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
创建新的BeanWrapper,new BeanWrapperImpl(beanInstance);
调用initBeanWrapper,设置beanWrapper的ConversionService,调用registerCustomEditors完成CustomEditors的注册:遍历beanFactory的propertyEditorRegistrars,调用registerCustomEditors方法,然后遍历beanFactory的customEditors,调用registerCustomEditors方法
返回beanWrapper
调用applyMergedBeanDefinitionPostProcessors:遍历beanFactory的BeanPostProcessors,调用他的postProcessMergedBeanDefinition方法
如果BeanDefinition是Singleton且allowCircularReferences且isSingletonCurrentlyInCreation(beanName)),调用addSingletonFactory将新创建的objectFactory加入到singletonFactories中(Eagerly cache singletons to be able to resolve circular references)
调用populateBean:
获取BeanDefinition的propertyValues;
如果BeanDefinition是Synthetic的并且beanFactory hasInstantiationAwareBeanPostProcessors,遍历BeanPostProcessors并调用InstantiationAwareBeanPostProcessor类型的postProcessAfterInstantiation方法
如果BeanDefinition的autowiremode为AUTOWIRE_BY_NAME,调用autowireByName方法:根据BeanDefinition的propertyValues属性,遍历,如果beanFactory中包含则调用getBean实例化,添加到MutablePropertyValues中,调用registerDependentBean方法将beanName和dependentName注册到dependentBeanMap、dependenciesForBeanMap中;
如果BeanDefinition的autowiremode为AUTOWIRE_BY_TYPE,调用autowireByType方法:先获取TypeConverter,根据BeanDefinition的propertyValues属性,遍历获取propertyDescriptor,然后获取BeanUtils.getWriteMethodParameter(pd),新建AutowireByTypeDependencyDescriptor对象并调用resolveDependency,将返回的对象加入到MutablePropertyValues中,调用registerDependentBean方法将beanName和dependentName注册到dependentBeanMap、dependenciesForBeanMap中;
如果hasInstantiationAwareBeanPostProcessors或BeanDefinition的DependencyCheck不等于DEPENDENCY_CHECK_NONE,调用filterPropertyDescriptorsForDependencyCheck忽略ignored dependency types或定义在ignored dependency interfaces上的属性
如果hasInstantiationAwareBeanPostProcessors,遍历BeanPostProcessors,调用InstantiationAwareBeanPostProcessor类型的postProcessPropertyValues方法;
如果BeanDefinition的DependencyCheck不等于DEPENDENCY_CHECK_NONE,调用checkDependencies检查所有暴露的Properties是否已经正确的设置;
调用applyPropertyValues,Apply the given property values, resolving any runtime references to other beans in this bean factory. Must use deep copy, so we don't permanently modify this property.
初始化bean,initializeBean:
调用invokeAwareMethods, 如果为BeanNameAware,setBeanName(beanName);如果为BeanClassLoaderAware,setBeanClassLoader(getBeanClassLoader());如果为BeanFactoryAware,setBeanFactory(AbstractAutowireCapableBeanFactory.this);
调用applyBeanPostProcessorsBeforeInitialization,遍历BeanPostProcessors并调用postProcessBeforeInitialization方法,如果返回值为null直接返回,不在继续调用后面BeanPostProcessors的postProcessBeforeInitialization方法
调用invokeInitMethods,如果为InitializingBean的实例,调用afterPropertiesSet方法;获取InitMethodName,调用invokeCustomInitMethod方法
调用applyBeanPostProcessorsAfterInitialization,遍历BeanPostProcessors并调用postProcessAfterInitialization方法,如果返回值为null直接返回,不在继续调用后面BeanPostProcessors的postProcessAfterInitialization方法
调用getSingleton从beanFactory的singletonObjects、earlySingletonObjects和singletonFactories中获取earlySingletonReference
如果beanFactory的allowRawInjectionDespiteWrapping为false并且hasDependentBean(beanName),获取DependentBeans,调用removeSingletonIfCreatedForTypeCheckOnly过滤,得到实际的DependentBeans
调用registerDisposableBeanIfNecessary:如果BeanDefinition不是prototype并且requiresDestruction,单例时调用registerDisposableBean为beanName注册一个新创建的DisposableBeanAdapter对象;不是单例时调用scope的registerDestructionCallback为beanName注册一个新创建的DisposableBeanAdapter对象
(2)调用getObjectForBeanInstance:
1)如果BeanFactoryUtils.isFactoryDereference(name)并且beanInstance不是FactoryBean的实例,抛出BeanIsNotAFactoryException;
2)getCachedObjectForFactoryBean:从beanFactory的factoryBeanObjectCache属性中获取,如果为空继续调用getMergedLocalBeanDefinition,然后调用getObjectFromFactoryBean
3)getObjectFromFactoryBean:如果FactoryBean是单例并且beanFactory包含他,从beanFactory的factoryBeanObjectCache属性中获取,如果为空,调用doGetObjectFromFactoryBean执行objectFactory的getObject()方法获取bean;否则调用doGetObjectFromFactoryBean,如果不为空,调用postProcessObjectFromFactoryBean,然后返回
10. 如果beanDefinition为isPrototype,先调用beforePrototypeCreation将beanName加入到prototypesCurrentlyInCreation中;然后调用createBean;调用afterPrototypeCreation将beanName从prototypesCurrentlyInCreation中移除;调用getObjectForBeanInstance;
11. 如果beanDefinition既不是singleton也不是prototype,先获取scope;然后调用scope的get方法,参数为beanName和新建的objectFactory,objectFactory的getObject方法中调用三个方法:beforePrototypeCreation(beanName)、createBean(beanName, mbd, args)、afterPrototypeCreation(beanName);调用getObjectForBeanInstance;
12. 检查required type是否匹配实际bean实例的类型,getTypeConverter().convertIfNecessary(bean, requiredType)
13. 返回bean
### Spring `getBean` 方法源码分析 #### 1. 初步调用链 在 Spring 中,`getBean` 是用于从容器中获取指定名称或类型的 Bean 的核心方法之一。通常情况下,开发者通过 `ApplicationContext` 或其子类来调用该方法。 测试代码展示了如何初始化一个基于 XML 配置文件的上下文并获取名为 `"userDao"` 的 Bean 实例[^1]: ```java @Test public void test_getBean() { BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring-config.xml"); UserDao userDao = beanFactory.getBean("userDao", UserDao.class); logger.info("获取 Bean:{}", userDao); } ``` 这里的 `beanFactory.getBean()` 方法最终会委托给 `AbstractBeanFactory.getBeans()` 进行处理[^3]。 --- #### 2. ApplicationContext 层级实现 当我们在 `ApplicationContext` 上调用 `getBean(Class<T> requiredType)` 时,实际上它是一个重载方法,内部逻辑如下所示[^2]: ```java @Override public <T> T getBean(Class<T> requiredType) throws BeansException { assertBeanFactoryActive(); // 委托 AbstractBeanFactory 处理具体逻辑 return getBeanFactory().getBean(requiredType); } ``` 这里的关键在于 `assertBeanFactoryActive()` 和 `getBeanFactory()` 的作用: - **`assertBeanFactoryActive()`**: 确保当前工厂处于活动状态。 - **`getBeanFactory()`**: 返回底层实际负责管理 Bean 定义和实例化的对象(通常是 `DefaultListableBeanFactory`)。 因此,控制权被进一步传递到 `AbstractBeanFactory` 类中的 `getBean` 方法。 --- #### 3. 抽象层的核心逻辑 进入 `AbstractBeanFactory` 后,可以看到它的简化版 `getBean(String name)` 方法定义如下: ```java public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } ``` 此方法的主要功能是将请求转发至更为复杂的私有方法 `doGetBean`,后者实现了大部分的实际业务逻辑。 --- #### 4. 主要逻辑分解 (`doGetBean`) 以下是 `doGetBean` 方法的部分伪代码结构,展示其实现细节的一部分: ```java protected <T> T doGetBean( final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { // Step 1: 解析传入的名字 (考虑别名情况) final String beanName = transformedBeanName(name); // Step 2: 检查缓存是否存在单例 Bean 实例 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { return getObjectForBeanInstance(sharedInstance, name, beanName, null); } // Step 3: 如果未找到,则创建新的 Bean 实例 RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); synchronized (mbd.getObjectLock()) { // 单例模式下再次尝试加载已存在的实例 sharedInstance = getSingleton(beanName); if (sharedInstance != null) { return getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } try { // 创建新 Bean 并返回 Object beanInstance = createBean(beanName, mbd, args); return (T) beanInstance; } catch (BeansException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of singleton failed", ex); } } } ``` 上述代码片段涵盖了以下几个重要阶段: 1. 名字转换与解析; 2. 缓存检查(优先利用已有单例实例); 3. 加载或构建新的 Bean 实例; 4. 错误捕获与异常抛出机制。 --- #### 5. 总结 整个 `getBean` 流程可以概括为以下几点: - 用户发起请求后,Spring 将逐步定位目标 Bean 的定义信息。 - 根据配置决定是否复用现有实例或者新建实例。 - 整个过程涉及多层封装以及多种优化策略,例如单例池管理和依赖注入支持。 更多深入的内容可参考完整的章节划分文档[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值