【Spring-5】AbstractBeanFactory#doGetBean创建实例完整流程

本文深入探讨Spring创建Bean的详细步骤,包括从缓存中获取实例、FactoryBean的特殊处理、创建前的准备工作(如检查父容器、创建依赖实例)、创建实例的逻辑(涉及postProcessBeforeInstantiation和doCreateBean方法),以及单例对象的处理。文章旨在全面理解Spring IoC容器的内部工作机制。
摘要由CSDN通过智能技术生成

本文详细分析spring创建对象的完整流程。
入口:AbstractBeanFactory#doGetBean

从缓存中取实例

		// 名称转换,如果传入的是别名会转换为bean的真正名称;如果是针对FactoryBean的,会去掉&
		String beanName = transformedBeanName(name);
		Object beanInstance;

		// 从缓存中取实例
		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 + "'");
				}
			}
			// 对FactoryBean类行的实例进行特殊处理
			beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

缓存逻辑

	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   
		// spring创建的缓存都是保存在singletonObjects这个map中的。
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
   
			singletonObject = this.earlySingletonObjects.get(beanName);
			if (singletonObject == null && allowEarlyReference) {
   
				synchronized (this.singletonObjects) {
   
					// Consistent creation of early reference within full singleton lock
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
   
						singletonObject = this.earlySingletonObjects.get(beanName);
						if (singletonObject == null) {
   
							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							if (singletonFactory != null) {
   
								singletonObject = singletonFactory.getObject();
								this.earlySingletonObjects.put(beanName, singletonObject);
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		return singletonObject;
	}

双检查加锁,缓存中没有的话,从暴露的引用中找,能找到就返回早期的引用;找不到就返回null。这里设计循环引用的逻辑,单独分析。。。

注意:
这里为什么会有三个缓存呢?
第一个缓存singletonObjects,用来保存已经实例化好,并且初始化好的的对象的
第二个缓存earlySingletonObjects,是用来保存已经实例化好的对象,但是没有初始化,所以他叫早期的单例对象,为的是解决循环依赖
第三个缓存singletonFactories,是创建对象的接口,可以理解为懒创建,等需要的时候再创建。

对FactoryBean类型的实例特殊处理

AbstractBeanFactory#getObjectForBeanInstance

protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
   

		// name如果是&开头,说明要的是FactoryBean的实例
		if (BeanFactoryUtils.isFactoryDereference(name)) {
   
			// 如果是nullBean直接返回
			if (beanInstance instanceof NullBean) {
   
				return beanInstance;
			}
			// 如果实例不是FactoryBean类型的,抛异常
			if (!(beanInstance instanceof FactoryBean)) {
   
				throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
			}
			// 如果是第一个创建,这个这个bd的属性是true
			if (mbd != null) {
   
				mbd.isFactoryBean = true;
			}
			// 返回实例,说明工厂中保存的是factoryBean的实例,如果用户要FactoryBean的实例,name一定是&开头,直接返回实例,如果不是&开头,就是下面的逻辑了。
			return beanInstance;
		}

		// 如果是普通的类型,直接返回实例。
		if (!(beanInstance instanceof FactoryBean)) {
   
			return beanInstance;
		}
		// 下面的逻辑是获得factoryBean中的普通类型的实例
		Object object = null;
		// 如果第一次创建,bd属性设置为true
		if (mbd != null) {
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引入一个依赖后,启动springboot报错:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultValidator' defined in class path resource [org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.AbstractMethodError: org.hibernate.validator.engine.ConfigurationImpl.getDefaultParameterNameProvider()Ljavax/validation/ParameterNameProvider; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:893) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
最新发布
06-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值