• Spring源码深度解析:八、bean的获取② - getSingleton


    一、前言

    文章目录:Spring源码深度解析:文章目录

    Spring源码分析七 :bean的加载① - doGetBean 文章中,我们介绍了Spring对获取bean的过程,但是并没有详细解释Bean是如何创建的,本文就来分析Spring是如何创建的bean

    bean的加载① - doGetBean 文章中我们知道DefaultSingletonBeanRegistry#getSingleton(java.lang.String, ObjectFactory)这一步创建了bean,如下图:
    在这里插入图片描述

    到了这一步,Spring就基本对Bean已经创建好的不抱什么希望了,所以着手开始自己创建bean
    本文就先来分析getSingleton(String beanName, ObjectFactory singletonFactory)方法整个流程。

    二、获取单例 - getSingleton

    具体代码如下:

    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    		Assert.notNull(beanName, "Bean name must not be null");
    		// 因为创建过程中需要操作singletonObjects。所以需要加锁
    		synchronized (this.singletonObjects) {
    			// 1. 再次尝试获取bean,判断bean是否已经加载。如果加载直接返回。
    			Object singletonObject = this.singletonObjects.get(beanName);
    			if (singletonObject == null) {
    				// 2. 判断,如果当前beanFactory正在被销毁则直接抛出异常,不允许创建单例bean
    				if (this.singletonsCurrentlyInDestruction) {
    					throw new BeanCreationNotAllowedException(beanName,
    							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
    							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
    				}
    				if (logger.isDebugEnabled()) {
    					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
    				}
    				// 3. 做一些bean创建前的准备工作:记录beanName正在加载的状态(添加到singletonsCurrentlyInCreation缓存中),若bean已经正在加载,则抛出异常。为了解决循环引用的问题
    				beforeSingletonCreation(beanName);
    				boolean newSingleton = false;
    				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
    				if (recordSuppressedExceptions) {
    					this.suppressedExceptions = new LinkedHashSet<>();
    				}
    				try {
    					// 4. 通过回调方式获取bean实例。
    					singletonObject = singletonFactory.getObject();
    					newSingleton = true;
    				}
    				catch (IllegalStateException ex) {
    					// Has the singleton object implicitly appeared in the meantime ->
    					// if yes, proceed with it since the exception indicates that state.
    					singletonObject = this.singletonObjects.get(beanName);
    					if (singletonObject == null) {
    						throw ex;
    					}
    				}
    				catch (BeanCreationException ex) {
    					if (recordSuppressedExceptions) {
    						for (Exception suppressedException : this.suppressedExceptions) {
    							ex.addRelatedCause(suppressedException);
    						}
    					}
    					throw ex;
    				}
    				finally {
    					if (recordSuppressedExceptions) {
    						this.suppressedExceptions = null;
    					}
    					// 5. 加载单例后的处理方法调用:删除bean正在创建的记录(从singletonsCurrentlyInCreation中移除beanName)
    					afterSingletonCreation(beanName);
    				}
    				if (newSingleton) {
    					// 6. 加入到缓存中,并删除加载bean过程中所记录的各种辅助状态
    					addSingleton(beanName, singletonObject);
    				}
    			}
    			return singletonObject;
    		}
    	}
    
    • 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

    上面的代码注释也比较清楚,基本流程如下:

    1. this.singletonObjects.get(beanName); :再次尝试从缓存中获取bean,若获取到,则直接返回。
    2. if (this.singletonsCurrentlyInDestruction) :未获取到检测bean是否正在销毁,若是则抛出异常
    3. beforeSingletonCreation():记录bean正在创建的状态将beanName添加到 singletonsCurrentlyInCreation集合中)。在循环依赖时可根据此判断。
    4. singletonObject = singletonFactory.getObject(); :调用ObjectFactory.getObject()方法来实例化bean
    5. afterSingletonCreation():删除bean正在创建的记录(从singletonsCurrentlyInCreation中移除beanName)
    6. addSingleton(beanName, singletonObject); : 加入到缓存中,并删除加载bean过程中所记录的各种辅助状态

    DefaultSingletonBeanRegistry#beforeSingletonCreation(String beanName)

    	/**
    	 * 不包含 && 添加失败 :则认为Bean正在创建中,抛出异常
    	 */
    	protected void beforeSingletonCreation(String beanName) {
    		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
    			throw new BeanCurrentlyInCreationException(beanName);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    DefaultSingletonBeanRegistry#afterSingletonCreation(String beanName)

    	/**
    	 * 不包含 && 移除失败 :认为Bean 已经创建结束,抛出异常。
    	 */
    	protected void afterSingletonCreation(String beanName) {
    		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
    			throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    DefaultSingletonBeanRegistry#addSingleton(String beanName, Object singletonObject)

    	/**
    	 * 主要还是对几个缓存map的操作
    	 */
    	protected void addSingleton(String beanName, Object singletonObject) {
    		synchronized (this.singletonObjects) {
    			this.singletonObjects.put(beanName, singletonObject);
    			this.singletonFactories.remove(beanName);
    			this.earlySingletonObjects.remove(beanName);
    			this.registeredSingletons.add(beanName);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    流程图如下所示 :
    在这里插入图片描述

    可以非常直观的看出, getSingleton 方法中的关键逻辑非常简单,bean创建的具体逻辑在singletonObject = singletonFactory.getObject();中,所以下面继续去分析singletonFactory.getObject()中做了什么。

    三、创建bean - createBean概述

    上面可以看到,主要步骤还是在回调的getObject()方法中。那么我们来看看在bean加载过程中的FactoryBean做了什么。代码如下:
    在这里插入图片描述
    兜了一大圈关键代码还是在createBean()方法里。接下来,我们就来仔细分析一下createBean()方法。
    AbstractBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)

    protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    			throws BeanCreationException;
    
    • 1
    • 2

    AbstractAutowireCapableBeanFactory#createBean()

    	@Override
    	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    			throws BeanCreationException {
    
    		if (logger.isDebugEnabled()) {
    			logger.debug("Creating instance of bean '" + beanName + "'");
    		}
    		RootBeanDefinition mbdToUse = mbd;
    
    		// 1. 锁定class, 根据mdb和beanName解析出来class
    		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    			mbdToUse = new RootBeanDefinition(mbd);
    			mbdToUse.setBeanClass(resolvedClass);
    		}
    
    		// Prepare method overrides.
    		try {
    			// 2. 验证及准备覆盖的方法
    			mbdToUse.prepareMethodOverrides();
    		}
    		catch (BeanDefinitionValidationException ex) {
    			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
    					beanName, "Validation of method overrides failed", ex);
    		}
    
    		try {
    			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    			// 3. 给beanPostProcessor一个返回目标类代理类的机会
    			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    			// 如果后处理器真的实现了,则直接返回使用后处理器的bean
    			if (bean != null) {
    				return bean;
    			}
    		}
    		catch (Throwable ex) {
    			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
    					"BeanPostProcessor before instantiation of bean failed", ex);
    		}
    
    		try {
    			// 4.  创建bean 的 真正方法
    			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    			if (logger.isDebugEnabled()) {
    				logger.debug("Finished creating instance of bean '" + beanName + "'");
    			}
    			return beanInstance;
    		}
    		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
    			// A previously detected exception with proper bean creation context already,
    			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
    			throw ex;
    		}
    		catch (Throwable ex) {
    			throw new BeanCreationException(
    					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    		}
    	}
    
    • 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

    可以看到,createBean 的整体流程大致如下:

    1. 根据设置的class属性或者根据className来解析Class。
    2. 对override 属性进行标记及验证。
    3. 应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作。
    4. 创建bean。
    5. 返回bean

    流程图如下:
    在这里插入图片描述

    四、创建bean - createBean详解

    上面的逻辑看着似乎不复杂,实际上,真正的逻辑都被封装在了方法中,所以下面需要关注如下的几个方法:

    1、resolveBeanClass()

    这里不再过多展示代码,这个方法的作用就是根据参数和返回值都能知道: 根据BeanDefinitionbeanName解析出beanClass

    	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    
    • 1

    2、prepareMethodOverrides()

    见名知意: 准备方法重写,这里更多是做一个校验的功能。这个方法主要是针对lookup-methodreplaced-method两个属性的,用来覆盖指定的方法。

    	mbdToUse.prepareMethodOverrides();
    
    • 1

    详细代码如下:
    AbstractBeanDefinition#prepareMethodOverrides()

    	public void prepareMethodOverrides() throws BeanDefinitionValidationException {
    		// Check that lookup methods exist and determine their overloaded status.
    		// // 判断是否有方法需要重写
    		if (hasMethodOverrides()) {
    			getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    AbstractBeanDefinition#prepareMethodOverride(MethodOverride mo)

    	protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
    		// 获取对应的类中的对应方法名的个数
    		int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
    		// 等于0抛出异常。上面已经验证有方法需要覆盖,这里为0肯定错误
    		if (count == 0) {
    			throw new BeanDefinitionValidationException(
    					"Invalid method override: no method with name '" + mo.getMethodName() +
    					"' on class [" + getBeanClassName() + "]");
    		}
    		else if (count == 1) {
    			// Mark override as not overloaded, to avoid the overhead of arg type checking.
    			// 标记 MethodOverride 暂未被覆盖,避免参数类型检查的开销。
    			mo.setOverloaded(false);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    解释一下上面的逻辑:

    1. 首先会判断是否有方法需要重写,这里的是根据RootBeanDefinition中的 methodOverrides属性来进行判断,为空则表示没有。
    2. 若上述判断有方法需要覆盖,则会调用prepareMethodOverride(MethodOverride mo)方法。而在prepareMethodOverride(MethodOverride mo)方法中会根据需要覆盖的方法名称 来获取加载类中关于该方法的实现。如果获取不到 count == 0,则直接抛出异常,如果获取到只有一个count == 1,则记录该方法并未被重载(因为Spring在方法匹配时,如果一个类中存在若干个重载方法,则在函数调用及增强的时候需要根据参数类型进行匹配,来最终确定调用的方法是哪一个,这里直接设置了该方法并未被重载,在后续方法匹配的时候就不需要进行参数匹配验证,直接调用即可)。
    3. 打个比方,比如指定覆盖A类中的 a方法,但是A类中可能存在多个a方法或者不存在a方法,若count == 0不 存在a方法,则谈何覆盖,直接抛出异常,若count ==1 则a方法的实现只有一个,标记该方法并未被重载后续可跳过参数验证的步骤。

    3、resolveBeforeInstantiation

    该方法主要是调用InstantiationAwareBeanPostProcessor来进行一些处理,这里实际上是给了用户一次代替Spring来创建bean的机会,代码实现上非常简单直接调用的后处理器方法。

    			// 3. 调用BeanProcessors的方法来替代真正的实例
    			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    			// 如果后处理器真的实现了,则直接返回使用后处理器的bean
    			if (bean != null) {
    				return bean;
    			}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    该方法调用了后处理器的方法:

    • InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation() : 在bean初始化前调用
    • BeanPostProcessor#postProcessAfterInitialization() : 在bean初始化后调用

    详细代码如下:在调用doCreate()方法创建bean的实例前调用了该方法对 BeanDefinition中的属性做一些前置处理。

    	@Nullable
    	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    		Object bean = null;
    		// 如果尚未被解析
    		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
    			// Make sure bean class is actually resolved at this point.
    			// 当前类并非合成类 && 存在 BeanPostProcessor (后处理器)
    			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    				// 1. 获取目标类
    				Class<?> targetType = determineTargetType(beanName, mbd);
    				// 2. 实例前的后处理器应用
    				if (targetType != null) {
    					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
    					if (bean != null) {
    						// 3. 实例后的后处理器应用
    						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    					}
    				}
    			}
    			mbd.beforeInstantiationResolved = (bean != null);
    		}
    		return bean;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    其中applyBeanPostProcessorsBeforeInstantiationapplyBeanPostProcessorsAfterInitialization很明显就是调用bean的后处理器,也就是对后处理器中的InstantiationAwareBeanPostProcessor类型的后处理器进行 postProcessBeforeInstantiation方法 和BeanPostProcessor类型的 postProcessAfterInitialization方法的调用。

    3.1 determineTargetType(beanName, mbd);

    关于factoryMethodName值的由来 这一点我们在 Spring源码深度解析:六、ConfigurationClassPostProcessor 中有过强调。即如果通过@Bean注入,则保存期工厂类的方法名称,简单来说就是配置类中对应该bean的注入方法名称。

    	@Nullable
    	protected Class<?> determineTargetType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
    		// 获取目标类。这里获取的目标类并不一定是真正生成的类,可能是其真正类的父类或者父接口
    		Class<?> targetType = mbd.getTargetType();
    		if (targetType == null) {
    			// 根据mdb 是否存在 factoryMethodName 来确定是直接解析class还是通过 工厂类的方法返回值来获取class
    			targetType = (mbd.getFactoryMethodName() != null ?
    					getTypeForFactoryMethod(beanName, mbd, typesToMatch) :
    					resolveBeanClass(mbd, beanName, typesToMatch));
    			if (ObjectUtils.isEmpty(typesToMatch) || getTempClassLoader() == null) {
    				mbd.resolvedTargetType = targetType;
    			}
    		}
    		return targetType;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    需要注意的是 这里获取的targetType类型并不一定是真正生成的bean类型,也可能是实际类型的父类或者父接口 。因为对于通过@Bean注解修饰注入到Spring容器的时候,BeanDefinitionfactoryMethodName属性值不为空,指向其工厂类的方法名。并且由于多态的特性,其工厂方法引入的类型并不一定是实际类型。这个类型的错误会在 AbstractAutowireCapableBeanFactory#doCreateBean()中纠正过来.

    比如 :下面的demoService()方法实际生成的类型是DemoServiceImpl。这里返回的类型是DemoService。那么我们这里获取到的targetType就是 DemoService.class。其BeanDefinition.factoryMethodName = demoService(即 DemoConfig 生成DemoService的方法的名称)

    public class DemoConfig {
        @Bean
        public DemoService demoService() {
            return new DemoServiceImpl();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3.2 postProcessBeforeInstantiation

    在bean 实例化前调用,也就是将AbstractBeanDefinition转换为BeanWrapper前的处理。给子类一个修改BeanDefinition的机会,也就是说当程序经过这个方法后,bean可能已经不是我们所认为的bean了。或许是一个经过代理的代理bean。可能是通过cglib生成的,也可能是通过其他技术生成的。
    AbstractAutowireCapableBeanFactoryapplyBeanPostProcessorsBeforeInstantiation(Class beanClass, String beanName)

    	@Nullable
    	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    		// 获取所有BeanPostProcessor进行遍历
    		for (BeanPostProcessor bp : getBeanPostProcessors()) {
    			if (bp instanceof InstantiationAwareBeanPostProcessor) {
    				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    				// 调用postProcessBeforeInstantiation方法
    				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
    				if (result != null) {
    					return result;
    				}
    			}
    		}
    		return null;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3.3 postProcessAfterInitialization

    这里是bean创建后的后置方法调用,逻辑基本类似。不同的是到达这一步时,Bean已经创建成功,并且注入属性也进行了赋值。

    需要注意,如果bean交由Spring来创建,那么Spring会将需要的属性注入到bean中,如果是自己代理生成(比如通过postProcessBeforeInstantiation方法生成),那么需要自己解决bean的属性注入问题。
    AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)

    	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    			throws BeansException {
    
    		Object result = existingBean;
    		for (BeanPostProcessor processor : getBeanPostProcessors()) {
    			Object current = processor.postProcessAfterInitialization(result, beanName);
    			if (current == null) {
    				return result;
    			}
    			result = current;
    		}
    		return result;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4、创建bean - doCreateBean

    代码执行到这里,可以确定第三步中并没有返回一个非空的bean(BeanPostProcessor 并没有代理生成一个bean)。所以Spring开始自己着手创建bean。do开头的方法才是真正做事情的,所以这里才是真正创建bean的地方。

    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    
    • 1

    具体代码如下:

    	/** 保存的是 FactoryBean 的beanName -> FactoryBean 的 BeanWrapper */
    	private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>(16);
    
    	// 创建Bean的核心方法
    	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    			throws BeanCreationException {
    
    		// 实例化Bean
    		// Instantiate the bean.
    		BeanWrapper instanceWrapper = null;
    		if (mbd.isSingleton()) {
    			// 有可能在本Bean创建之前,就有其他Bean把当前Bean给创建出来(比如依赖注入过程中)
    			// 单例情况下清除缓存。这里保存的是 FactoryBean 和 BeanWrapper 的映射关系。
    			// factoryBeanInstanceCache是在创建其他bean的时候缓存了一下FactoryBean 。
    			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    		}
    		// 如果没有缓存,则重新创建
    		if (instanceWrapper == null) {
    			// 1. 创建Bean实例:根据指定的bean使用对应的策略创建新的实例。如:工厂方法、构造函数自动注入,简单初始化
    			instanceWrapper = createBeanInstance(beanName, mbd, args);
    		}
    		// 获取bean实例
    		Object bean = instanceWrapper.getWrappedInstance();
    		// 获取bean类型
    		Class<?> beanType = instanceWrapper.getWrappedClass();
    		// 将目标类型替换成实际生成的类型.纠正了上面说到类型错误(如果存在)
    		if (beanType != NullBean.class) {
    			mbd.resolvedTargetType = beanType;
    		}
    
    		// 2. 调用 MergedBeanDefinitionPostProcessor 后处理器,后置处理合并后的BeanDefinition
    		// Allow post-processors to modify the merged bean definition.
    		synchronized (mbd.postProcessingLock) {
    			if (!mbd.postProcessed) {
    				try {
    					// 调用MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition后处理器的方法。
    					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.
    		// 3. 判断是否需要提早曝光:单例 & 允许循环依赖 & 当前bean已经正在创建中
    		// 由于当前bean已经在创建中,本次创建必然是循环引用造成的,所以这里判断是否可以需要提前曝光
    		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
    				isSingletonCurrentlyInCreation(beanName));
    		if (earlySingletonExposure) {
    			if (logger.isDebugEnabled()) {
    				logger.debug("Eagerly caching bean '" + beanName +
    						"' to allow for resolving potential circular references");
    			}
    			// 4. 为避免后期循环依赖,在bean初始化完成前将创建实例的ObjectFactory加入工程  -- 解决循环依赖:添加到三级缓存
    			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    		}
    
    		// Initialize the bean instance.
    		Object exposedObject = bean;
    		try {
    			// 5. 对bean进行属性填充,将各个属性值注入,其中如果存在依赖于其他bean的属性,则会递归初始依赖bean
    			populateBean(beanName, mbd, instanceWrapper);
    			// 调用初始化方法,比如 init-method
    			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);
    			}
    		}
    
    		// 6. 进行循环依赖检查
    		if (earlySingletonExposure) {
    			Object earlySingletonReference = getSingleton(beanName, false);
    			// earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
    			if (earlySingletonReference != null) {
    				// 如果exposedObject没有在初始化方法中被改变,也就是没有被增强
    				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);
    						}
    					}
    					// 因为bean创建后其所依赖的bean一定是已经创建了的。actualDependentBeans不为空说明当前bean创建后其依赖的bean却没有全部创建完,也就说说存在循环依赖。
    					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 {
    			// 7.根据Scopse 注册bean
    			registerDisposableBeanIfNecessary(beanName, bean, mbd);
    		}
    		catch (BeanDefinitionValidationException ex) {
    			throw new BeanCreationException(
    					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    		}
    
    		return exposedObject;
    	}
    
    • 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
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123

    大致逻辑如下:

    1. createBeanInstance(beanName, mbd, args) :实例化bean,将BeanDefinition转换为BeanWrapper
    2. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); MergedBeanDefinitionPostProcessor后处理器的应用。bean合并后的处理,比如 @Autowired@Value注解正是通过 AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition()此方法实现的预解析。
    3. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); : 关于循环依赖的处理,添加ObjectFactory到singletonFactories缓存中,同时这里给了用户一个机会通过调用SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference方法来由用户生成暴露的实例
    4. populateBean(beanName, mbd, instanceWrapper); :对创建的bean内部的一些属性进行填充注入
    5. initializeBean(beanName, exposedObject, mbd); : 初始化bean的一些属性,如Aware接口的实现,init-method属性等
    6. 循环依赖检查。和第四步不同的是,这里了是判断是否无法解决循环依赖,否则抛出异常。
    7. registerDisposableBeanIfNecessary(beanName, bean, mbd); : 注册DisposableBean
    8. 完成创建并返回。

    4.1 createBeanInstance

    见名知意 : 该方法完成了bean的实例创建。

    instanceWrapper = createBeanInstance(beanName, mbd, args);
    
    • 1

    大概逻辑可以概括为:

    1. 如果存在工厂方法则使用工厂方法进行初始化
    2. 若类有多个构造函数,则根据参数锁定构造函数并初始化
    3. 如果即不存在工厂方法也不存在带参构造函数,则使用默认的构造函数进行bean的实例化。

    具体的代码分析已成文 :Spring源码深度解析:九、bean的获取② - createBeanInstance

    4.2 applyMergedBeanDefinitionPostProcessors

    这种方法命名的也见得多了,见名知意: 该方法完成了MergedBeanDefinitionPostProcessors后处理器的功能。主要是 bean合并后的处理。在 AutowiredAnnotationBeanPostProcessorpostProcessMergedBeanDefinition方法的实现中,就对@Autowired、@Value 等注解进行了一系列的预处理,这里我们并不需要太过在意。
    AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors()

    	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
    		for (BeanPostProcessor bp : getBeanPostProcessors()) {
    			if (bp instanceof MergedBeanDefinitionPostProcessor) {
    				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
    				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4.3 addSingletonFactory

    这一部分的逻辑就是为了解决循环依赖的问题,将未创建完成的当前bean,通过ObjectFactory进行一个包装,提前暴露给其他bean。

    具体代码如下:

    		// 3. 判断是否需要提早曝光:单例 & 允许循环依赖 & 当前bean已经正在创建中
    		// 由于当前bean已经在创建中,本次创建必然是循环引用造成的,所以这里判断是否可以需要提前曝光
    		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
    				isSingletonCurrentlyInCreation(beanName));
    		if (earlySingletonExposure) {
    			if (logger.isDebugEnabled()) {
    				logger.debug("Eagerly caching bean '" + beanName +
    						"' to allow for resolving potential circular references");
    			}
    			// 4. 为避免后期循环依赖,在bean初始化完成前将创建实例的ObjectFactory加入工程  -- 解决循环依赖:添加到三级缓存
    			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    首先我们需要分析出earlySingletonExposure为true的条件:

    • bean是单例
    • 允许循环依赖
    • 当前bean正在创建中 :singletonsCurrentlyInCreation包含当前bean。在Spring中有专门的属性记录bean的加载状态 – DefaultSingletonBeanRegistry#singletonsCurrentlyInCreation()。在bean创建前会将bean添加,bean创建结束后将bean移除。这一点我们在前篇有过提及。
      满足上述三个条件后,则会调用addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); 方法。为避免后期循环依赖,在bean初始化完成前将创建实例的ObjectFactory加入工程 – 解决循环依赖:添加到三级缓存

    DefaultSingletonBeanRegistry#addSingletonFactory()

    protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    		Assert.notNull(singletonFactory, "Singleton factory must not be null");
    		synchronized (this.singletonObjects) {
    			if (!this.singletonObjects.containsKey(beanName)) {
    				this.singletonFactories.put(beanName, singletonFactory);
    				this.earlySingletonObjects.remove(beanName);
    				this.registeredSingletons.add(beanName);
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    AbstractAutowireCapableBeanFactory#getEarlyBeanReference()

    	 
    	/** 
    	 * 给调用者一次机会,主要就是调用了SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference()方法。将getEarlyBeanReference方法的返回值作为提前暴露的对象。
    	 * 我们可以通过实现 getEarlyBeanReference()方法来替代Spring提前暴露的对象
    	 * Aop就是在这里将Advice动态织入bean中,若没有bean则直接返回bean,不做任何处理
    	 */
    	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
    		Object exposedObject = bean;
    		// 当前类并非合成类 && 在hasInstantiationAwareBeanPostProcessors中
    		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    			for (BeanPostProcessor bp : getBeanPostProcessors()) {
    				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
    					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
    					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
    				}
    			}
    		}
    		return exposedObject;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    该方法中getEarlyBeanReference调用了后处理器的方法,可用于用户自己扩展替换Spring生成的提前暴露的对象 :

    4.4 populateBean

    见名知意,下面这个方法是用来属性注入的。
    populateBean()方法则是对bean属性的注入,上面的createBeanInstance方法创建了 bean,但是其内部属性并没有注入,比如通过@Autowired注解注入的变量属性,此时还为null,需要对这种属性进行注入,这一步就是完成这种功能。

    	populateBean(beanName, mbd, instanceWrapper);
    
    • 1

    这里方法里按照如下顺序调用了后处理器

    1. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation : 返回true 才会调用下面两个方法
    2. InstantiationAwareBeanPostProcessor.postProcessProperties : 进行属性的注入。
    3. InstantiationAwareBeanPostProcessor.postProcessPropertyValues : 已过时

    篇幅所限,详细的代码分析请阅 Spring源码深度解析:十、bean的属性注入④ - populateBean

    4.5 initializeBean

    到达这一步,其实bean已经创建结束了,这一步是完成最后的功能,提供一些功能的实现,如Aware 接口的实现, init-method、InitializingBean属性等。
    AbstractAutowireCapableBeanFactory#initializeBean()

    	exposedObject = initializeBean(beanName, exposedObject, mbd);
    
    • 1
    	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    		// 对特殊的bean进行处理: 实现了Aware、BeanClassLoaderAware、BeanFactoryAware的处理。
    		if (System.getSecurityManager() != null) {
    			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    				// 激活Aware方法
    				invokeAwareMethods(beanName, bean);
    				return null;
    			}, getAccessControlContext());
    		}
    		else {
    			invokeAwareMethods(beanName, bean);
    		}
    
    		Object wrappedBean = bean;
    
    		// 初始化前
    		if (mbd == null || !mbd.isSynthetic()) {
    			// 调用了bean前处理器的方法
    			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    		}
    
    		// 初始化
    		try {
    			// 激活自定义的init的方法。
    			invokeInitMethods(beanName, wrappedBean, mbd);
    		}
    		catch (Throwable ex) {
    			throw new BeanCreationException(
    					(mbd != null ? mbd.getResourceDescription() : null),
    					beanName, "Invocation of init method failed", ex);
    		}
    
    		// 初始化后
    		if (mbd == null || !mbd.isSynthetic()) {
    			// 调用bean后处理器的方法
    			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    		}
    
    		return wrappedBean;
    	}
    
    • 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

    上面关于两个后处理器的调用,本文就不再赘述了,分别调用了 BeanPostProcessor. postProcessBeforeInitialization()BeanPostProcessor.postProcessAfterInitialization()方法。

    所以我们主要分析下面两个方法 :

    1. 激活Aware方法 - invokeAwareMethods

    这个方法很简单,完成了 Aware 接口的激活功能。可以简单的说 :

    • 如果bean实现了BeanNameAware接口,则将beanName设值进去
    • 如果bean实现了BeanClassLoaderAware接口,则将ClassLoader设值进去
    • 如果bean实现了BeanFactoryAware接口,则将beanFactory设值进去
    private void invokeAwareMethods(String beanName, Object bean) {
    		if (bean instanceof Aware) {
    			if (bean instanceof BeanNameAware) {
    				((BeanNameAware) bean).setBeanName(beanName);
    			}
    			if (bean instanceof BeanClassLoaderAware) {
    				ClassLoader bcl = getBeanClassLoader();
    				if (bcl != null) {
    					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
    				}
    			}
    			if (bean instanceof BeanFactoryAware) {
    				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    这里简单解释一下 Aware的作用。从上面的代码可以看到,实现不同类型的 Aware 接口会接受到不同得到初始化数据。

    举个例子: 如果bean实现了BeanFactoryAware接口,那么他就可以在bean内部获取到beanFacotory

    其实Aware接口的作用,我在分析AutowiredAnnotationBeanPostProcessor后处理器的时候才突然想明白的。 AutowiredAnnotationBeanPostProcessor中完成了Bean的属性和方法注入,属性要从BeanFactory的缓存中获取,那么AutowiredAnnotationBeanPostProcessor如何得到的beanFactory呢? 答案是实现了BeanFactoryAware接口。这样在AutowiredAnnotationBeanPostProcessor初始化的时候就通过
    void setBeanFactory(BeanFactory beanFactory)获取到beanFactory。如下图。AutowiredAnnotationBeanPostProcessor保存了setBeanFactory带来的beanFactory,并通过此来从容器中获取需要的bean。
    在这里插入图片描述

    2. invokeInitMethods - 激活自定义的init方法

    首先需要注意的是,Bean 的初始化方法除了可以使用init-method属性(或者 @Bean(initMethod=‘’”)),还可以通过实现InitializingBean接口,并且在afterPropertiesSet方法中实现自己初始化的业务逻辑。

    调用顺序则是afterPropertiesSet先调用,后面调用init-method指定的方法。这一点从下面的代码逻辑就能看到

    protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
    			throws Throwable {
    		// 首先检查是否是InitializingBean,如果是的话则需要调用 afterPropertiesSet 方法。
    		boolean isInitializingBean = (bean instanceof InitializingBean);
    		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
    			if (logger.isDebugEnabled()) {
    				logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
    			}
    			// 调用 afterPropertiesSet  方法
    			if (System.getSecurityManager() != null) {
    				try {
    					AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
    						((InitializingBean) bean).afterPropertiesSet();
    						return null;
    					}, getAccessControlContext());
    				}
    				catch (PrivilegedActionException pae) {
    					throw pae.getException();
    				}
    			}
    			else {
    				((InitializingBean) bean).afterPropertiesSet();
    			}
    		}
    
    		if (mbd != null && bean.getClass() != NullBean.class) {
    			// 从RootBeanDefinition 中获取initMethod 方法名称
    			String initMethodName = mbd.getInitMethodName();
    			// 调用initMethod 方法。
    			if (StringUtils.hasLength(initMethodName) &&
    					!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
    					!mbd.isExternallyManagedInitMethod(initMethodName)) {
    				invokeCustomInitMethod(beanName, bean, mbd);
    			}
    		}
    	}
    
    
    • 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

    4.6 循环依赖检查

    Spring 循环依赖的解决仅对单例且非构造函数构造的形式有效,对于原型模式的bean,Spring直接抛出异常,在这个步骤中会检测已经加载的bean 是否已经出现了循环依赖,并判断是否需要抛出异常。

    // 6. 进行循环依赖检查
    		if (earlySingletonExposure) {
    			Object earlySingletonReference = getSingleton(beanName, false);
    			// earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
    			if (earlySingletonReference != null) {
    				// 如果exposedObject没有在初始化方法中被改变,也就是没有被增强
    				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);
    						}
    					}
    					// 因为bean创建后其所依赖的bean一定是已经创建了的。actualDependentBeans不为空说明当前bean创建后其依赖的bean却没有全部创建完,也就说说存在循环依赖。
    					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.");
    					}
    				}
    			}
    		}
    	// 上面调用的 getSingleton 方法。可以知道这里传递的 allowEarlyReference 为false。
    	// 因为当前bean在进行循环创建的时候,就已经将 bean缓存到 earlySingletonObjects 中了
    	@Nullable
    	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    		Object singletonObject = this.singletonObjects.get(beanName);
    		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
    			synchronized (this.singletonObjects) {
    				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;
    	}
    
    • 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
    • 上面调用的getSingleton()方法。可以知道这里传递的allowEarlyReference为false。因为当前bean在进行循环创建的时候,就已经将 bean缓存到earlySingletonObjects中了

    DefaultSingletonBeanRegistry#getSingleton(String beanName, boolean allowEarlyReference)

    @Nullable
    	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    		// 尝试从单例缓存(一级缓存) singletonObjects 中获取完整的Bean。
    		Object singletonObject = this.singletonObjects.get(beanName);
    		// 如果单例缓存(一级缓存)中没有对象,创建中的Bean的名字会被保存在singletonsCurrentlyInCreation中
    		// 也就是说,当前所需要获取的bean是否是singleton的,并且处于创建中的形态
    		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
    			// 如果单例缓存中不存在该bean,则加锁进行接下来的处理
    			// 这里作为锁还有一个原因是二级缓存和三级缓存都是HashMap,需要一个锁来控制这两个map的操作
    			synchronized (this.singletonObjects) {
    				// 尝试从二级缓存earlySingletonObjects中获取半成品的Bean, 则直接将singletonObject返回。
    				// 二级缓存存储的是未对属性进行添加的Bean.
    				singletonObject = this.earlySingletonObjects.get(beanName);
    				// 如果还获取不到,并且allowEarlyReference为true,则表示可以进行循环引用
    				if (singletonObject == null && allowEarlyReference) {
    					// 从三级缓存singletonFactories这个ObjectFactory实例的缓存中尝试获取创建此Bean的单例工厂实例
    					// ObjectFactory为用户定制(容器中的代理Bean),FactoryBean框架会进行特殊处理(自定义)
    					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
    					if (singletonFactory != null) {
    						// 调用单例工厂的getObject方法获取对象实例
    						singletonObject = singletonFactory.getObject();
    						// 将实例放入二级缓存中.
    						this.earlySingletonObjects.put(beanName, singletonObject);
    						// 从三级缓存中删除
    						this.singletonFactories.remove(beanName);
    					}
    				}
    			}
    		}
    		return singletonObject;
    	}
    
    • 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
    • 删除给定bean名称的单例实例(如果有的话),但前提是该类型仅用于类型检查以外的用途。
      AbstractBeanFactory#removeSingletonIfCreatedForTypeCheckOnly(String beanName)
    	protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) {
    		if (!this.alreadyCreated.contains(beanName)) {
    			removeSingleton(beanName);
    			return true;
    		}
    		else {
    			return false;
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    FactoryBeanRegistrySupport#removeSingleton(String beanName)

    	@Override
    	protected void removeSingleton(String beanName) {
    		synchronized (getSingletonMutex()) {
    			super.removeSingleton(beanName);
    			this.factoryBeanObjectCache.remove(beanName);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    DefaultSingletonBeanRegistry#removeSingleton(String beanName)

    	protected void removeSingleton(String beanName) {
    		synchronized (this.singletonObjects) {
    			this.singletonObjects.remove(beanName);
    			this.singletonFactories.remove(beanName);
    			this.earlySingletonObjects.remove(beanName);
    			this.registeredSingletons.remove(beanName);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    整个逻辑如下:

    1. getSingleton(beanName, false); : 从缓存中获取缓存对象,这传递的false, 直接从 earlySingletonObjects中获取循环依赖的对象earlySingletonReference
    2. 如果earlySingletonReference == bean ,说明bean没有被修改,直接赋值即可。
    3. 如果earlySingletonReference != bean ,那么说明 在 下面的代码中,bean被修改了
    	populateBean(beanName, mbd, instanceWrapper);
    	exposedObject = initializeBean(beanName, exposedObject, mbd);
    
    • 1
    • 2

    此时需获取依赖于当前bean的dependentBeans。如果dependentBeans中有已经创建好的,那么则抛出异常

    4.7 registerDisposableBeanIfNecessary

    这一步的目的是实现destory-method属性,如果bean配置了该属性,则需要注册以便在销毁时调用。

    详细代码如下:

    	protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    		AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
    		if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
    			if (mbd.isSingleton()) {
    				// Register a DisposableBean implementation that performs all destruction
    				// work for the given bean: DestructionAwareBeanPostProcessors,
    				// DisposableBean interface, custom destroy method.
    				// 单例模式下注册需要销毁的bean,此方法会处理实现DisposableBean的bean
    				// 并且对所有的bean使用 DestructionAwareBeanPostProcessor 处理 DisposableBean DestructionAwareBeanPostProcessor
    				registerDisposableBean(beanName,
    						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
    			}
    			else {
    				// A bean with a custom scope...
    				// 自定义 scope 的处理
    				Scope scope = this.scopes.get(mbd.getScope());
    				if (scope == null) {
    					throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
    				}
    				scope.registerDestructionCallback(beanName,
    						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    竞赛选题 深度学习乳腺癌分类
    resnet152 辣椒病虫害图像识别1.0
    5分钟无需编码完成页面搭建
    【深度学习】Python 快速入门
    Linux 指令心法(十二)`rm` 永久性地删除文件或目录
    CSDN 编程竞赛·第八期总结
    redis与 缓存击穿、缓存穿透、缓存雪崩
    基于语义分割的相机外参标定
    Java线程休眠与中断
    VR失重太空舱游乐设备|航空航天VR体验|VR航天航空体验馆
  • 原文地址:https://blog.csdn.net/wts563540/article/details/127985797