当前位置: 首页 > news >正文

Spring容器Bean的创建流程

文章目录

  • 前言
  • 1. Bean创建流程概览
  • 2. 源码分析
    • 2.1 getBean()
    • 2.2 doGetBean()
    • 2.3 getSingleton()
    • 2.4 createBean()
    • 2.5 doCreateBean()
  • 3. 时序图概括
  • 总结

前言

本文将从源码角度分析Spring容器中Bean的创建流程,重点关注从getBean()方法开始的完整调用链路,通过源码分析Spring IoC容器的核心工作机制。

1. Bean创建流程概览

getBean()方法开始,Spring Bean的创建流程如下:

getBean() → doGetBean() → getSingleton() → createBean() → doCreateBean()

2. 源码分析

2.1 getBean()

@Override
public Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);
}@Override  
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {return doGetBean(name, requiredType, null, false);
}

这是Bean获取的统一入口,所有的getBean重载方法最终都会调用doGetBean()方法。

2.2 doGetBean()

protected <T> T doGetBean(final String name, final Class<T> requiredType,final Object[] args, boolean typeCheckOnly) throws BeansException {// 第1步:转换Bean名称final String beanName = transformedBeanName(name);Object bean;// 第2步:检查单例缓存,解决循环依赖Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {// 如果是FactoryBean,调用getObject()方法bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {// 第3步:检查原型Bean是否存在循环依赖if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}// 第4步:检查父容器BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {return parentBeanFactory.getBean(originalBeanName(name), requiredType);}// 第5步:标记Bean为已创建状态if (!typeCheckOnly) {markBeanAsCreated(beanName);}try {// 第6步:获取Bean定义,合并父Bean定义final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);// 第7步:处理depends-on依赖String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dep : dependsOn) {registerDependentBean(dep, beanName);getBean(dep); // 递归创建依赖的Bean}}// 第8步:创建Bean实例if (mbd.isSingleton()) {// 单例模式sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {try {return createBean(beanName, mbd, args);} catch (BeansException ex) {destroySingleton(beanName);throw ex;}}});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}else if (mbd.isPrototype()) {// 原型模式Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}else {// 其他作用域(request、session等)String scopeName = mbd.getScope();final Scope scope = this.scopes.get(scopeName);Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}}});bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}}catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName);throw ex;}}returnthis.adaptBeanInstance(name, beanInstance, requiredType);;
}

2.3 getSingleton()

// DefaultSingletonBeanRegistry.java
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "Bean name must not be null");synchronized (this.singletonObjects) {// 先从一级缓存获取Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {// 检查是否正在销毁if (this.singletonsCurrentlyInDestruction) {throw new BeanCreationNotAllowedException(beanName, "...");}// 创建前的准备工作beforeSingletonCreation(beanName);boolean newSingleton = false;boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<Exception>();}try {// 调用ObjectFactory创建BeansingletonObject = singletonFactory.getObject();newSingleton = true;}catch (IllegalStateException ex) {}finally {if (recordSuppressedExceptions) {this.suppressedExceptions = null;}// 创建后的清理工作afterSingletonCreation(beanName);}if (newSingleton) {// 将新创建的单例添加到缓存中addSingleton(beanName, singletonObject);}}return singletonObject;}
}

2.4 createBean()

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {RootBeanDefinition mbdToUse = mbd;// 第1步:解析Bean的Class类型Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// 第2步:准备方法覆盖try {mbdToUse.prepareMethodOverrides();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);}try {// 第3步:给BeanPostProcessor一个机会返回代理对象Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean; // 如果返回了代理对象,直接返回}}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);}// 第4步:执行实际的Bean创建Object beanInstance = doCreateBean(beanName, mbdToUse, args);return beanInstance;
}

2.5 doCreateBean()

// AbstractAutowireCapableBeanFactory.java - 最核心的Bean创建方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd,final Object[] args) throws BeanCreationException {// Bean包装器BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {// 第1步:实例化BeaninstanceWrapper = createBeanInstance(beanName, mbd, args);}final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);mbd.resolvedTargetType = beanType;// 第2步:允许post-processor修改MergedBeanDefinitionsynchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}}// 第3步:解决循环依赖boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {addSingletonFactory(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {return getEarlyBeanReference(beanName, mbd, bean);}});}// 第4步:初始化Bean实例Object exposedObject = bean;try {// 属性填充populateBean(beanName, mbd, instanceWrapper);if (exposedObject != null) {// 初始化BeanexposedObject = initializeBean(beanName, exposedObject, mbd);}}catch (Throwable ex) {if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;}else {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Initialization of bean failed", ex);}}// 第5步:处理循环依赖的检查if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;}else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,"Bean with name '" + beanName + "' has been injected into other beans [" +StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +"] in its raw version as part of a circular reference, but has eventually been " +"wrapped. This means that said other beans do not use the final version of the " +"bean. This is often the result of over-eager type matching - consider using " +"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");}}}}// 第6步:注册DisposableBeantry {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;
}

3. 时序图概括

ClientBeanFactorySingletonRegistryBeanCreatorBeanInstancegetBean(name)doGetBean()getSingleton(name)createBean()doCreateBean()实例化属性填充初始化完整Bean加入一级缓存alt[Bean不存在]Bean实例Bean实例ClientBeanFactorySingletonRegistryBeanCreatorBeanInstance

总结

在学习SpringIoC容器中Bean是如何创建的过程中,我翻阅的无数次源码,也借鉴了很多大佬的文章,一次一次的打断点需要很大的耐心,虽然现在的学习没有得到正反馈,但是在将来的一天当你把源码烂熟于心是,不管是写博客总结还是在面试中被问到,可以胸有成竹的回答出来。希望大家可以更好的理解Bean的创建流程。

http://www.dtcms.com/a/342660.html

相关文章:

  • 使用jwt+redis实现单点登录
  • Matplotlib+HTML+JS:打造可交互的动态数据仪表盘
  • Android - 统一资源标识符 Uri
  • 利用DeepSeek编写调用系统命令用正则表达式替换文件中文本的程序
  • [NCTF2019]True XML cookbook
  • PyTorch Vision 系列:高效数据处理的利器
  • 动手学深度学习(pytorch版):第五章节—深度学习计算(2)参数管理
  • 进程和进程调度
  • Rclone入门对象存储云到云迁移
  • 我从零开始学微积分(2)- 函数与图形
  • YOLO --- YOLOv3以及YOLOv4模型详解
  • Redis Hash数据类型深度解析:从命令、原理到实战场景
  • IPSEC安全基础后篇
  • 易焓仪器安全帽耐熔融金属飞溅性能测试仪:飞溅场景适配与精准检测
  • 力扣 30 天 JavaScript 挑战 第37天 第九题笔记 知识点: 剩余参数,拓展运算符
  • 智慧农业温室大棚远程监控物联网系统解决方案
  • CRaxsRat v7.4:网络安全视角下的深度解析与防护建议
  • AECS(国标ECALL GB 45672-2025)
  • 5G视频终端详解 无人机图传 无线图传 便携式5G单兵图传
  • 汇总图片拖进ps中 photoshop同时打开几个文件夹
  • 【论文阅读 | TCSVT 2025 | CFMW:面向恶劣天气下鲁棒目标检测的跨模态融合Mamba模型】
  • 深入理解Docker网络:从docker0到自定义网络
  • 设计简洁的Ansible:目前非常流行的开源配置管理和自动化工具
  • webrtc中win端音频---windows Core Audio
  • Mysql基础(②锁)
  • 想在手机上操作服务器?cpolar让WaveTerminal终端随身携带,效率倍增
  • 高并发短信网关平台建设方案概述
  • 打造医疗新质生产力
  • nodejs安装后 使用npm 只能在cmd 里使用 ,但是不能在poowershell使用,只能用npm.cmd
  • ES_多表关联