spring框架源码十七、Bean对象创建子流程

news2025/7/12 15:06:58

Bean对象创建子流程

  • Bean对象创建子流程
    • new ClassPathXmlApplicationContext
    • ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String)
    • ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String[], boolean, org.springframework.context.ApplicationContext)
    • AbstractApplicationContext#refresh
    • AbstractApplicationContext#finishBeanFactoryInitialization
    • DefaultListableBeanFactory#preInstantiateSingletons
    • AbstractBeanFactory#getBean(java.lang.String)
    • AbstractBeanFactory#doGetBean
      • 标记bean开始被创建,this.alreadyCreated.add(beanName)
      • 1、DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
        • 标记bean正在被创建,this.singletonsCurrentlyInCreation.add(beanName)
      • 2、AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
    • AbstractAutowireCapableBeanFactory#doCreateBean

Bean对象创建子流程

Bean对象创建的入口,
AbstractApplicationContext#finishBeanFactoryInitialization

new ClassPathXmlApplicationContext

在这里插入图片描述

ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String)

在这里插入图片描述

ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String[], boolean, org.springframework.context.ApplicationContext)

在这里插入图片描述

AbstractApplicationContext#refresh

在这里插入图片描述

AbstractApplicationContext#finishBeanFactoryInitialization

Bean对象创建子流程的入口,

在这里插入图片描述

DefaultListableBeanFactory#preInstantiateSingletons

实例化所有立即加载的单例bean,

在这里插入图片描述

	@Override
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// 存放所有的beanName,即beanID
		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				// 如果是factoryBean则加'&'前缀
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					// 实例化当前bean
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}
	

AbstractBeanFactory#getBean(java.lang.String)

在这里插入图片描述

AbstractBeanFactory#doGetBean

标记bean开始被创建,this.alreadyCreated.add(beanName)

在这里插入图片描述

	/**
	 * Return an instance, which may be shared or independent, of the specified bean.
	 * @param name the name of the bean to retrieve
	 * @param requiredType the required type of the bean to retrieve
	 * @param args arguments to use when creating a bean instance using explicit arguments
	 * (only applied when creating a new instance as opposed to retrieving an existing one)
	 * @param typeCheckOnly whether the instance is obtained for a type check,
	 * not for actual use
	 * @return an instance of the bean
	 * @throws BeansException if the bean could not be created
	 */
	@SuppressWarnings("unchecked")
	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		String beanName = transformedBeanName(name);
		Object bean;

		// 从缓存中获取bean
		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// 如果bean的scope是prototype模式,且允许循环依赖,则抛出异常
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}

			if (!typeCheckOnly) {
				// 标记bean开始被创建,this.alreadyCreated.add(beanName)
				markBeanAsCreated(beanName);
			}

			try {
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				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) {
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						registerDependentBean(dep, beanName);
						try {
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// 创建单例bean
				// Create bean instance.
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							// 创建
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					String scopeName = mbd.getScope();
					if (!StringUtils.hasLength(scopeName)) {
						throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
					}
					Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; consider " +
								"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		// Check if required type matches the type of the actual bean instance.
		if (requiredType != null && !requiredType.isInstance(bean)) {
			try {
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				if (convertedBean == null) {
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			}
			catch (TypeMismatchException ex) {
				if (logger.isTraceEnabled()) {
					logger.trace("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

1、DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)

标记bean正在被创建,this.singletonsCurrentlyInCreation.add(beanName)

在这里插入图片描述

2、AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])

在这里插入图片描述

AbstractAutowireCapableBeanFactory#doCreateBean

真正创建bean的地方,

	/**
	 * Actually create the specified bean. Pre-creation processing has already happened
	 * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
	 * <p>Differentiates between default bean instantiation, use of a
	 * factory method, and autowiring a constructor.
	 * @param beanName the name of the bean
	 * @param mbd the merged bean definition for the bean
	 * @param args explicit arguments to use for constructor or factory method invocation
	 * @return a new instance of the bean
	 * @throws BeanCreationException if the bean could not be created
	 * @see #instantiateBean
	 * @see #instantiateUsingFactoryMethod
	 * @see #autowireConstructor
	 */
	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);
		}
		if (instanceWrapper == null) {
			// 创建bean实例,调用了构造方法,尚未设置属性
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		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) {
				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;
			}
		}

		// 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) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// 初始化bean实例
		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			// 设置属性
			populateBean(beanName, mbd, instanceWrapper);
			
			// 调用初始化方法,然后完成bean创建
			exposedObject = 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);
			}
		}

		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<>(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 " +
								"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/17956.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

冒泡事件在Vue中的应用

什么是事件冒泡&#xff1f; 一想到“冒泡”这两个词会想到什么&#xff1f;想必然&#xff0c;那就是气泡自下而上的从水底往上生的场景&#xff0c;但是我们也知道&#xff0c;水在往上升的过程中&#xff0c;也会经历不同的高度。由此场景&#xff0c;那么想必然&#xff0c…

JavaEE 进阶:Spring 核⼼与设计思想

文章目录一、Spring 是什么1、什么是容器2、什么是 IoC① 传统程序开发Ⅰ 轮胎尺寸固定a. 代码b. 缺陷Ⅱ 轮胎尺寸改变a. 代码b. 缺陷② 控制反转式程序开发Ⅰ 控制反转Ⅱ 需求增加Ⅲ 优点③ 对⽐总结规律3、理解 Spring IoC4、DI 概念说明一、Spring 是什么 Spring是当前Java…

Windows安装nginx

Windows安装nginx1.下载Nginx2.Nginx的使用2.1 修改nginx.conf2.2 启动nginx3.可能出现的问题观前提示&#xff1a; 本文所使用的系统Windows10。 1.下载Nginx Nginx官网&#xff0c;点击download下载 根据需求下载自己所需版本&#xff0c;这里我下载的是稳定版本 2.Nginx的…

链表

章节目录&#xff1a;一、链表1.1 概述二、单向链表2.1 实现思路2.2 代码示例三、双向链表3.1 实现思路3.2 代码示例四、单向环形链表4.1 约瑟夫问题4.2 实现思路4.3 代码示例五、结束语一、链表 1.1 概述 链表是一种物理存储单元上非连续、非顺序的存储结构&#xff0c;数据元…

谷粒学院(一) 项目环境搭建

一、数据库设计 数据库设计规约 以下规约只针对本模块&#xff0c;更全面的文档参考《阿里巴巴Java开发手册》&#xff1a;五、MySQL数据库 1、库名与应用名称尽量一致 2、表名、字段名必须使用小写字母或数字&#xff0c;禁止出现数字开头&#xff0c; 3、表名不使用复数名…

idea导入springboot项目运行教程

前置要求 ①具备Java环境&#xff0c;并且可以通过Maven进行安装项目依赖&#xff1b; ②具备IntelliJ IDEA工具&#xff0c;推荐专业版&#xff0c;社区版也不影响&#xff1b; ③具备Mysql5.7或以上版本数据库&#xff1b; ④具备Navicat数据库可视化管理工具&#xff1b;…

力扣(LeetCode)14. 最长公共前缀(C++)

模拟 取出 strsstrsstrs 的第一个字符串 strs[0]strs[0]strs[0] &#xff0c; 遍历strs[0]strs[0]strs[0] &#xff0c; 依次比较所有串的当前位置的字符&#xff0c;是否和 strs[0]strs[0]strs[0] 的当前字符相同。 代码展示 class Solution { public:string longestCommon…

现代修谱,如何处理族员离婚再娶,配偶携子改嫁同服弟等情况

现代修谱的那些糟心事 现代修谱过程中&#xff0c;会遇到各种突发情况以及非常棘手的问题。比如说族员离婚再娶&#xff0c;配偶携子改嫁同服弟的情况&#xff0c;族谱该如何记载&#xff1f;很多人都以为这是笔者在说笑&#xff0c;但这种情况在修谱时&#xff0c;不能说很难…

Qt源码解析11-QLineEdit与QValidator关系源码解析

Qt源码解析 索引 Qt源码解析11-QLineEdit与QValidator关系源码解析 测试 本想了解QRegExpValidator的正则表达式如何生效的&#xff0c;发现分析起来比想象的复杂。 测试实例&#xff1a; // regexp: optional - followed by between 1 and 3 digitsQRegExp rx("-?\…

JUC学习笔记——共享模型之管程

在本系列内容中我们会对JUC做一个系统的学习&#xff0c;本片将会介绍JUC的管程部分 我们会分为以下几部分进行介绍&#xff1a; 共享问题共享问题解决方案线程安全分析Monitorsynchronized锁Wait/notify模式之保护性暂停模式之生产者消费者park线程状态转换详解多锁操作活跃…

学生护眼灯怎么选择?推荐学生护眼台灯十大名牌排行榜

护眼台灯是学生们常用的照明产品&#xff0c;也是最受喜爱的护眼产品之一&#xff0c;选购一款护眼台灯要看什么指标呢&#xff1f;除了外观、价格上&#xff0c;更重要的是五个硬性标准&#xff0c;照度、显色、频闪、色温、蓝光。 为了大家更快速选择出合适的台灯&#xff0…

基于51单片机的出租车计价器proteus仿真原理图PCB

功能&#xff1a; 0.本系统采用STC89C52作为单片机 1.LCD1602液晶显示有四个状态 a) 时间显示 b) 时间设置 c) 计价器显示 d) 计价器设置 2.按键切换四个不同显示状态 3.默认为时间显示状态&#xff0c;长按’切换‘键切换至计价器模式 4.在时间显示状态下按‘设置’键可设置时…

C++类的运算符重载.md

11.8 类的运算符重载 运算符重载是一种形式的C多态 运算符重载将充值该的概念扩展到运算符上&#xff0c;允许赋予C运算符多种含义。 C允许将运算符重载扩展到用户定义类型&#xff0c;例如&#xff0c;允许使用将两个对象相加。 11.8.1 操作符重载定义 要重载运算符&#xff0…

FutureTask-详解(二)-ThreadPollExecutor-并发编程(Java)

文章目录1 FutureTask1.1 简介1.2 成员变量1.3 构造方法1.4 主要执行流程分析1.4.1 run任务执行1.4.1.1 run方法1.4.1.2 set(result)方法1.4.1.3 setException(ex)方法1.4.1.4 finishCompletion()方法1.4.2 get() 执行流程1.4.2.1 get()方法1.4.2.2 awaitDone()方法1.4.2.3 rem…

C++获取计算机硬件信息(Linux)

C获取计算机硬件信息&#xff08;Windows&#xff09; https://blog.csdn.net/hhy321/article/details/121258036 C获取计算机硬件信息&#xff08;Linux&#xff09; https://blog.csdn.net/hhy321/article/details/127930470 “春赏百花秋望月&#xff0c;夏有凉风冬观雪。若…

InnoDB之Undo log写入和恢复

1. 前言 为了实现事务的回滚和MVCC&#xff0c;InnoDB设计了Undo log模块&#xff0c;简单来说就是在修改记录前先记下日志&#xff0c;以便之后能将记录恢复成修改前的样子。针对insert、delete、update这三种不同的操作&#xff0c;InnoDB设计了不同类型的undo log&#xff…

Redis 常见问题

一、 什么是Redis&#xff1f; Redis 是一个使用 C 语言写成的&#xff0c;开源的高性能key-value非关系缓存数据库&#xff1b;Redis的数据都基于缓存的&#xff0c;所以很快&#xff0c;每秒可以处理超过 10万次读写操作&#xff1b;Redis也可以实现数据写入磁盘中&#xff…

Spring源码里开天辟地的五个Bean,再介绍一个学习方法

准备工作 首先咱们还是来写一个最简单的例子&#xff1a; 用的还是 https://github.com/xiexiaojing/yuna 里的代码&#xff0c;只是标签和引用都换成了Spring原生的。 配置类就是配置了扫描路径&#xff1a; 在可以被扫描的包路径下定义了一个Bean对象。用了Component注解这…

Java#16(包装类和集合练习)

目录 基本数据类型对应的包装类: 一.添加学生对象并遍历 二.添加用户对象并判断是否存在 三.添加手机对象并返回要求的数据 基本数据类型对应的包装类: byte------>Byte short------->Short char------->Character int------->Integer long------->Long flo…

MRT(MODIS Reprojection Tool) 下载及安装教程

大家下载MODIS数据的时候&#xff0c;大多是hdf的格式数据。HDF数据包括11个波段的数据&#xff08;如下图&#xff09;&#xff0c;假如想要其中一个波段数据&#xff0c;我们需要批量提取&#xff0c;这时就要用到NASA提供的MODIS Reprojection Tool&#xff0c;此工具虽不能…