spring注解驱动系列--Bean生命周期一

目录

一、Bean生命周期

二、管理Bean生命周期 

三、生命周期

一、构造(对象创建)

二、 postProcessorsBeforeInitialization

三、 初始化

四、postProcessAfterInitialization 

五、销毁

六、对于指定初始化和销毁方法

一、通过@Bean指定init-method和destroy-method

二、通过让Bean实现InitializingBean(定义初始化逻辑),DisposableBean(定义销毁逻辑)

三、可以使用JSR250:

七、初始化前后执行,BeanPostProcessor【interface】:bean的后置处理器: 

四、Bean创建工作原理

一、spring首先会调用getBean方法进行获取单实例(多实例是每次都会创建)bean,如果获取不到就会调用createBean进行bean的创建。(这里就类似于使用缓存,先从缓存中获取,获取不到就创建(类似于从数据库中读取))

二、createBean方法里面的doCreateBean方法进行对象的创建,以下是对createBean方法的大致解析以及对doCreateBean方法之前所有方法的详细解析。doCreateBean方法之前都是对创建实例bean的准备

一、createBean方法大致解析

二、createBean方法里面,doCreateBean方法之前所有方法的详细解析

三、 创建Bean

一、createBeanInstance方法

1、如果在RootBeanDefinition中存在instanceSupplier属性,那么Spring会尝试调用obtainFromSupplier(instanceSupplier, beanName, mbd)方法根据RootBeanDefinition中的配置生成bean的实例

2、如果在RootBeanDefinition中存在factoryMethodName属性,或者说在配置文件中配置了factory-method,那么Spring会尝试使用instantiateUsingFactoryMethod(beanName, mbd, args)方法根据RootBeanDefinition中的配置生成bean的实例。源码如下:

3、解析构造函数并进行构造函数的实例化。因为一个bean对应的类中可能会有多个构造函数,而每个构造函数的参数不同,Spring在根据参数及类型去判断最终会使用哪个构造函数进行实例化。判断的过程是个比较耗时的过程,所以采用缓存机制。

4、实例策略

二、提前缓存单实例,解决循环依赖

三、属性注入

1、autowireByName方法 

2、autowireByType


一、Bean生命周期

bean创建---  BeanPostProcessor.postProcessorsBeforeInitialization---初始化----BeanPostProcessor.postProcessAfterInitialization ----销毁的过程

二、管理Bean生命周期 

在Bean的生命周期中,我们可以认为的进行干预Bean的创建到销毁的过程,也就是我们可以自定义初始化和销毁方法,容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。从而达到我们想要的一些业务效果。

三、生命周期

一、构造(对象创建)

分为,

单实例:在容器启动的时候创建对象
多实例:在每次获取的时候创建对象

二、 postProcessorsBeforeInitialization

BeanPostProcessor(bean的后置处理器)接口中postProcessorsBeforeInitialization方法,在初始化之前工作调用,每个bean都会执行这个方法

三、 初始化

对象创建完成,并赋值好,调用初始化方法。

四、postProcessAfterInitialization 

BeanPostProcessor(bean的后置处理器)接口中postProcessAfterInitialization 方法,在初始化之后工作调用,每个bean都会执行这个方法 

五、销毁

单实例:容器关闭的时候
多实例:容器不会管理这个bean;容器不会调用销毁方法; 

六、对于指定初始化和销毁方法

一、通过@Bean指定init-method和destroy-method

@Bean(initMethod="init",destroyMethod="detory")

二、通过让Bean实现InitializingBean(定义初始化逻辑),DisposableBean(定义销毁逻辑)

@Component
public class Cat implements InitializingBean,DisposableBean {
	
	public Cat(){
		System.out.println("cat constructor...");
	}

	@Override
	public void destroy() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("cat...destroy...");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("cat...afterPropertiesSet...");
	}

}

三、可以使用JSR250:

 1、@PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
 2、@PreDestroy:在容器销毁bean之前通知我们进行清理工作

@Component
public class Dog {
	
	//@Autowired
	private ApplicationContext applicationContext;
	
	public Dog(){
		System.out.println("dog constructor...");
	}
	
	//对象创建并赋值之后调用
	@PostConstruct
	public void init(){
		System.out.println("Dog....@PostConstruct...");
	}
	
	//容器移除对象之前
	@PreDestroy
	public void detory(){
		System.out.println("Dog....@PreDestroy...");
	}

}

七、初始化前后执行,BeanPostProcessor【interface】:bean的后置处理器: 

在bean初始化前后进行一些处理工作;
 1、postProcessBeforeInitialization:在初始化之前工作
 2、postProcessAfterInitialization:在初始化之后工作     

/**
 * 后置处理器:初始化前后进行处理工作
 * 将后置处理器加入到容器中
 */
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// TODO Auto-generated method stub,这个bean也可以进行包装之后再返回
		System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
		return bean;
	}

}

四、Bean创建工作原理

一、spring首先会调用getBean方法进行获取单实例(多实例是每次都会创建)bean,如果获取不到就会调用createBean进行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;
						}
					});
					beanInstance = 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);
					}
					beanInstance = 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);
							}
						});
						beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new ScopeNotActiveException(beanName, scopeName, ex);
					}
				}

源码说明:

        主要是调用createBean函数来创建Bean的,该函数是一个类的中心方法,用于创建bean实例,包括填充bean实例,应用后处理器等。它首先确保bean类在该点上实际解析,并在动态解析的类的情况下克隆bean定义。然后准备方法覆盖,并给BeanPostProcessors一个机会返回一个代理对象而不是目标bean实例。最后,它调用doCreateBean函数来创建bean实例,并在完成后返回该实例。如果出现异常,将抛出BeanCreationException异常。

二、createBean方法里面的doCreateBean方法进行对象的创建,以下是对createBean方法的大致解析以及对doCreateBean方法之前所有方法的详细解析。doCreateBean方法之前都是对创建实例bean的准备

一、createBean方法大致解析
	/**
	 * 此类的中心方法:创建bean实例,填充bean实例,应用后处理器等。
	 * @see #doCreateBean
	 */
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
 
		if (logger.isTraceEnabled()) {
			logger.trace("创建 bean '" + beanName + "' 的实例");
		}
		RootBeanDefinition mbdToUse = mbd;
 
		// 确保在此时刻 bean 类已解析,并且在解析为动态类的情况下,克隆 bean 定义
		// 以便无法存储在共享合并的 bean 定义中。
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}
 
		// 准备方法覆盖。
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "方法覆盖的验证失败", ex);
		}
 
		try {
			// 给 BeanPostProcessors 一个机会,返回一个代理而不是目标 bean 实例。
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					" bean 创建之前的 BeanPostProcessor 失败", ex);
		}
 
		try {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("完成 bean '" + beanName + "' 的实例创建");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// 已经有适当的 bean 创建上下文的先前检测到的异常,或者是传递给 DefaultSingletonBeanRegistry 的非法单例状态。
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "在 bean 创建过程中出现意外异常", ex);
		}
	}
二、createBean方法里面,doCreateBean方法之前所有方法的详细解析

1、resolveBeanClass方法:根据设置的class属性或者className解析Class

resolveBeanClass函数用于解析指定的bean定义,将bean类名转换为Class引用,并将解析后的Class存储在bean定义中以供以后使用。如果解析过程中出现错误,将抛出CannotLoadBeanClassException异常。源码如下:

/** * 解析指定bean定义的bean类, 
 * 将bean类名转换为Class引用(如果需要的话) 
 * 并将解析后的Class存储在bean定义中以供进一步使用。 
 * @param mbd 要确定类的合并的bean定义 
 * @param beanName bean的名称(用于错误处理目的) 
 * @param typesToMatch 内部类型匹配目的下的要匹配的类型 
 * (也表示返回的 {@code Class} 将永远不会暴露给应用程序代码)
 * @return 解析后的bean类(如果不存在则为 {@code null})
 * @throws CannotLoadBeanClassException 如果我们无法加载类
 */
	@Nullable
	protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
			throws CannotLoadBeanClassException {
 
		try {
			if (mbd.hasBeanClass()) {
				return mbd.getBeanClass();
			}
			return doResolveBeanClass(mbd, typesToMatch);
		}
		catch (ClassNotFoundException ex) {
			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
		}
		catch (LinkageError err) {
			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
		}
	}

上面的函数依然是将主要的处理逻辑放到doResolveBeanClass函数中的,源码如下:

	/**
	 * 解析bean的类
	 * @param mbd bean的定义
	 * @param typesToMatch 用于匹配的类列表
	 * @return 解析后的类
	 * @throws ClassNotFoundException 如果类解析失败
	 */
	@Nullable
	private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) throws ClassNotFoundException {
 
	    ClassLoader beanClassLoader = getBeanClassLoader();
	    ClassLoader dynamicLoader = beanClassLoader;
	    boolean freshResolve = false;
 
	    if (!ObjectUtils.isEmpty(typesToMatch)) {
	        // 在仅进行类型检查(即尚未创建实际实例)的情况下,使用指定的临时类加载器(例如在织入场景中)
	        ClassLoader tempClassLoader = getTempClassLoader();
	        if (tempClassLoader != null) {
	            dynamicLoader = tempClassLoader;
	            freshResolve = true;
	            if (tempClassLoader instanceof DecoratingClassLoader dcl) {
	                for (Class<?> typeToMatch : typesToMatch) {
	                    dcl.excludeClass(typeToMatch.getName());
	                }
	            }
	        }
	    }
 
	    String className = mbd.getBeanClassName();
	    if (className != null) {
	        Object evaluated = evaluateBeanDefinitionString(className, mbd);
	        if (!className.equals(evaluated)) {
	            // 4.2开始支持动态解析表达式...
	            if (evaluated instanceof Class<?> clazz) {
	                return clazz;
	            }
	            else if (evaluated instanceof String name) {
	                className = name;
	                freshResolve = true;
	            }
	            else {
	                throw new IllegalStateException("Invalid class name expression result: " + evaluated);
	            }
	        }
	        if (freshResolve) {
	            // 在针对临时类加载器进行解析时,为了不将解析后的Class保存在bean定义中,请提前退出
	            if (dynamicLoader != null) {
	                try {
	                    return dynamicLoader.loadClass(className);
	                }
	                catch (ClassNotFoundException ex) {
	                    if (logger.isTraceEnabled()) {
	                        logger.trace("无法从" + dynamicLoader + "加载类[" + className + "]: " + ex);
	                    }
	                }
	            }
	            return ClassUtils.forName(className, dynamicLoader);
	        }
	    }
 
	    // 按照常规方式解析,并将结果缓存在BeanDefinition中
	    return mbd.resolveBeanClass(beanClassLoader);
	}

函数的作用是解析bean的类。它首先获取bean的类加载器和临时类加载器,然后根据typesToMatch参数判断是否需要使用临时类加载器。如果需要,它会将dynamicLoader设置为临时类加载器,并将freshResolve设置为true。然后它获取mbd中的beanClassName,如果非空,它会根据beanClassName进行评估。如果评估结果与beanClassName不同,它会根据评估结果的类型返回类或者更新beanClassName和freshResolve的值。如果在使用临时类加载器时出现类未找到的异常,它会尝试从dynamicLoader中加载类,如果成功,返回加载的类,否则返回null。最后,如果beanClassName为空,它会按照常规方式解析并缓存结果在BeanDefinition中。下面是doResolveBeanClass函数中最后一行mbd.resolveBeanClass(beanClassLoader);中的方法

	/**
	 * 根据指定的类加载器解析包装的bean的类,如果需要的话从指定的类名中解析。当已解析出bean的类时,根据类名重新加载一个指定的Class。
	 * @param classLoader 用于解析(潜在的)类名的类加载器
	 * @return 解析出的bean类
	 * @throws ClassNotFoundException 如果无法解析类名
	 */
	@Nullable
	public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
	    String className = getBeanClassName();
	    if (className == null) {
	        return null;
	    }
	    Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
	    this.beanClass = resolvedClass;
	    return resolvedClass;
	}

2、prepareMethodOverrides()方法:

该函数用于验证和准备该bean定义的Method Overrides(方法重写)。它检查是否存在具有指定名称的方法,并在验证失败时抛出异常。如果存在方法重写,则对于每个重写方法,它会调用prepareMethodOverride函数进行准备。

	/**
	 * 验证并准备此bean定义的方法重写。
	 * 检查是否存在指定名称的方法。
	 * @throws BeanDefinitionValidationException 如果验证失败
	 */
	public void prepareMethodOverrides() throws BeanDefinitionValidationException {
	    // 检查查找方法是否存在,并确定其重载状态。
	    if (hasMethodOverrides()) {
	        getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
	    }
	}

prepareMethodOverride(注意与prepareMethodOverrides方法不是同一个)函数用于验证和准备给定的方法重写。它检查指定名称的方法是否存在,如果没有找到,则将其标记为非重载。如果验证失败,则会抛出BeanDefinitionValidationException异常。如果找到一个方法,则将重写标记为非重载,以避免参数类型检查的开销。

getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);,以下是prepareMethodOverride源码

	/**
	 * 验证并准备给定的方法覆盖。
	 * 检查是否存在指定名称的方法,
	 * 如果没有找到,则将其标记为非重载。
	 * @param mo 需要验证的 MethodOverride 对象
	 * @throws BeanDefinitionValidationException 如果验证失败
	 */
	protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
	    int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
	    if (count == 0) {
	        throw new BeanDefinitionValidationException(
	                "Invalid method override: no method with name '" + mo.getMethodName() +
	                "' on class [" + getBeanClassName() + "]");
	    }
	    else if (count == 1) {
	        // 将 override 标记为非重载,以避免参数类型检查的开销。
	        mo.setOverloaded(false);
	    }
	}

 3、resolveBeforeInstantiation方法:实例化的前置处理

该函数用于在实例化之前应用前置处理器,判断是否存在指定bean的前置实例化快捷方式。如果存在快捷方式,则返回快捷方式确定的bean实例。如果不存在,则返回null。

	/**
	 * 在实例化之前应用前置处理器,确定是否为指定 bean 存在实例化前的快捷方式。
	 *
	 * @param beanName bean 的名称
	 * @param mbd bean 定义
	 * @return 前置处理器确定的 bean 实例,如果不存在则返回 null
	 */
	@SuppressWarnings("deprecation")
	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
	    Object bean = null;
	    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
	        // 确保在此刻 bean 类已经解析。
	        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
	            Class<?> targetType = determineTargetType(beanName, mbd);
	            if (targetType != null) {
	                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
	                if (bean != null) {
	                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
	                }
	            }
	        }
	        mbd.beforeInstantiationResolved = (bean != null);
	    }
	    return bean;
	}

 resolveBeforeInstantiation里面的applyBeanPostProcessorsBeforeInstantiation函数用于应用InstantiationAwareBeanPostProcessor来调用postProcessBeforeInstantiation方法,该方法可以对指定的bean定义进行处理。处理后的返回值将被用作bean对象,而不是实例化目标bean。如果postProcessor返回null,则会实例化目标bean。以下是applyBeanPostProcessorsBeforeInstantiation方法源码:

	/**
	 * 对指定的 bean 定义(按类和名称)应用 InstantiationAwareBeanPostProcessors,
	 * 调用它们的 postProcessBeforeInstantiation 方法。
	 * <p>任何返回的对象将用作 bean,而不是实际实例化目标 bean。
	 * 如果后处理器返回 null,则会实例化目标 bean。
	 * @param beanClass 要实例化的 bean 的类
	 * @param beanName bean 的名称
	 * @return 用于替代目标 bean 的默认实例的 bean 对象,或为 null
	 * @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
	 */
	@Nullable
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
	    for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
	        Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
	        if (result != null) {
	            return result;
	        }
	    }
	    return null;
	}

 applyBeanPostProcessorsAfterInitialization函数在bean初始化后应用bean后处理器,按照bean处理器的顺序依次对bean进行处理,直到所有bean处理器返回结果。如果bean处理器返回null,则直接返回原始bean结果。

	/**
	 * 应用初始化后对bean进行后处理
	 *
	 * @param existingBean 存在的bean对象
	 * @param beanName bean名称
	 * @return 后处理结果
	 * @throws BeansException 如果在后处理过程中出现异常,抛出BeansException异常
	 * @since 6.1
	 */
	@Deprecated(since = "6.1")
	@Override
	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;
	}

三、 创建Bean

当经历过resolveBeforeInstantiation方法后,程序有两个选择,如果创建了代理或者说重写了InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法并在方法postProcessBeforeInstantiation中改变了bean,则直接返回就可以了。否则要进行常规bean的创建,而这常规bean的创建就是在doCreateBean中完成的。

	/**
	 * 实际创建指定的bean。在这一点上已经发生了预创建处理,例如检查`postProcessBeforeInstantiation`回调。
	 * 区分默认bean实例化、使用工厂方法和自动装配构造函数。
	 * @param beanName bean的名称
	 * @param mbd 合并的bean定义
	 * @param args 显式的参数用于构造方法调用
	 * @return 新的bean实例
	 * @throws BeanCreationException 如果无法创建bean
	 * @see #instantiateBean
	 * @see #instantiateUsingFactoryMethod
	 * @see #autowireConstructor
	 */
	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
	    // 实例化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;
		}
 
		// 允许后处理处理器修改合并的bean定义。
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"合并的bean定义后处理失败", ex);
				}
				mbd.markAsPostProcessed();
			}
		}
 
		// 在允许解决潜在循环引用时提前缓存单例能够解决循环引用
		// 即使是由像BeanFactoryAware这样的生命周期接口触发的。
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("提前缓存bean '" + beanName +
						"'以允许解决潜在的循环引用");
			}
            // 为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}
 
		// 初始化bean实例。
		Object exposedObject = bean;
		try {
            // 对Bean进行填充,将各个属性值注入,其中,可能存在依赖于其他Bean的属性,
            // 则会递归初始依赖Bean
			populateBean(beanName, mbd, instanceWrapper);
            // 调用初始化方法,比如init-method
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException bce && beanName.equals(bce.getBeanName())) {
				throw bce;
			}
			else {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName, ex.getMessage(), ex);
			}
		}
 
		if (earlySingletonExposure) {
            // earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
			Object earlySingletonReference = getSingleton(beanName, false);
			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.");
					}
				}
			}
		}
 
		// 注册bean为可销毁的。
		try {
            // 根据scope注册bean
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "无效的销毁签名", ex);
		}
 
		return exposedObject;
	}

该函数用于实际创建指定的bean对象,包括默认的bean实例化、使用工厂方法和构造器自动连接。该函数还处理缓存单例对象、初始化bean实例和注册bean为可销毁对象。如果bean创建失败,将抛出BeanCreationException异常。

该函数的整个逻辑的思路是:

1、如果是单例则需要首先清除缓存。

2、实例化bean,将BeanDefinition转换为BeanWrapper。转换过程是一个复杂的过程,我们可以尝试概括大致的过程:

如果存在工厂方法则使用工厂方法进行初始化。
一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化。
如果既不存在工厂方法也不存在带有参数的构造函数,则使用默认的构造函数进行Bean的实例化。
3、MergedBeanDefinitionPostProcessor的应用,Bean合并后的处理,Autowired注解正是通过此方法实现诸如类型的预解析。

4、依赖处理,在Spring中会有循环依赖的情况,例如当A中有B的属性,而B中又含有A的属性时就会构成一个循环依赖,此时如果A和B都是单例,那么Spring中的处理方式就是当创建B的时候,涉及自动注入A的步骤时,并不是直接去再次创建A,而是通过放入缓存中的ObjectFactory来创建实例,这样就解决了循环依赖的问题。

5、属性填充。将所有属性填充至Bean的实例中

6、循环依赖检查,在Spring中解决循环依赖只对单例有效,而对于prototype的bean,Spring没有好的解决办法,唯一要做的就是抛出异常。

7、注册DisposableBean,如果设置了destroy-method,这里需要注册以便于在销毁时候调用。

8、完成创建并返回

下面是doCreateBean方法中创建bean的createBeanInstance方法源码

一、createBeanInstance方法
	/**
	 * 创建指定 bean 的新实例,使用适当的行为策略:工厂方法、构造函数自动装配或简单实例化。
	 * @param beanName bean 的名称
	 * @param mbd bean 定义为 bean 的定义
	 * @param args 显式参数用于构造函数或工厂方法调用
	 * @return 一个 BeanWrapper 用于新实例
	 * @see #obtainFromSupplier
	 * @see #instantiateUsingFactoryMethod
	 * @see #autowireConstructor
	 * @see #instantiateBean
	 */
	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// 确保 bean 类在这个点已经被解析。
		Class<?> beanClass = resolveBeanClass(mbd, beanName);
 
		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean 类不是 public,并且不允许非公共访问: " + beanClass.getName());
		}
 
        // 如果创建bean实例的回调函数不为空,就是用回调函数创建Bean实例
		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName, mbd);
		}
 
        // 如果工厂方法不为空则使用工厂方法初始化策略
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}
 
		// 当重新创建相同的 bean 时的快捷方式...
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
                // 一个类有多个构造函数,每个构造函数都有不同的参数,所以调用前需要
                // 先根据参数锁定构造函数或对应的工厂方法
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
 
        // 如果已经解析过,则使用解析好的构造函数方法,不需要再次锁定
		if (resolved) {
			if (autowireNecessary) {
                // 构造函数自动注入
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
                // 使用默认构造函数构造Bean实例
				return instantiateBean(beanName, mbd);
			}
		}
 
		// 需要根据参数解析构造函数
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}
 
		// 默认构造函数的首选构造函数?
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
            // 构造函数自动注入
			return autowireConstructor(beanName, mbd, ctors, null);
		}
 
		// 没有特殊处理:默认使用无参构造函数。
		return instantiateBean(beanName, mbd);
	}

这个函数用于创建指定 bean 的新实例,

1、采用适当 的实例化策略:工厂方法、构造函数自动装配或简单实例化。根据给定的 bean 名称、bean 定义和显式参数,返回一个包含新实例的 BeanWrapper。

2、如果 bean 类在该点上实际解析了,将使用 resolveBeanClass 方法解析 bean 类。

3、然后,根据 bean 类的访问修饰符和非公共访问是否允许的设置来判断是否需要抛出异常。

4、然后,根据 RootBeanDefinition 的实例供应商来判断是否需要从供应商中获取实例,如果需要,则调用 obtainFromSupplier 方法。如果工厂方法名称不为空,则调用 instantiateUsingFactoryMethod 方法。如果重新创建相同的 bean,则通过 args 是否为 null 来判断是否需要进行实例化。如果需要实例化,则调用 autowireConstructor 方法或 instantiateBean 方法。如果不需要实例化,则直接返回 instantiateBean 方法。如果 bean 类的构造函数需要进行自动装配,则调用 autowireConstructor 方法。如果 bean 类有默认的构造函数,则调用 autowireConstructor 方法。

5、最后,如果没有特殊处理,直接使用无参构造函数进行实例化。

以下是createBeanInstance方法中的方法

1、如果在RootBeanDefinition中存在instanceSupplier属性,那么Spring会尝试调用obtainFromSupplier(instanceSupplier, beanName, mbd)方法根据RootBeanDefinition中的配置生成bean的实例
/**
 * 从给定的供应商获取一个bean实例。
 * @param supplier 配置好的供应商
 * @param beanName 对应的bean名称
 * @return 一个用于新实例的BeanWrapper
 */
private BeanWrapper obtainFromSupplier(Supplier<?> supplier, String beanName, RootBeanDefinition mbd) {
    String outerBean = this.currentlyCreatedBean.get();
    this.currentlyCreatedBean.set(beanName);
    Object instance;
 
    try {
        instance = obtainInstanceFromSupplier(supplier, beanName, mbd);
    }
    catch (Throwable ex) {
        if (ex instanceof BeansException beansException) {
            throw beansException;
        }
        throw new BeanCreationException(beanName, "供应的bean的实例化失败", ex);
    }
    finally {
        if (outerBean != null) {
            this.currentlyCreatedBean.set(outerBean);
        }
        else {
            this.currentlyCreatedBean.remove();
        }
    }
 
    if (instance == null) {
        instance = new NullBean();
    }
    BeanWrapper bw = new BeanWrapperImpl(instance);
    initBeanWrapper(bw);
    return bw;
}

这个函数从给定的供应商获取一个bean实例,并返回一个用于这个新实例的BeanWrapper。如果实例化bean失败,则抛出BeanCreationException。如果实例为null,则创建一个NullBean。最后,使用新实例初始化BeanWrapper并返回。其中调用函数obtainInstanceFromSupplier获取bean实例。

obtainInstanceFromSupplier是obtainFromSupplier方法中的方法

	/**
	 * 从给定的回调函数获取一个bean实例。
	 *
	 * @param supplier 配置好的回调函数
	 * @param beanName 对应的bean名称
	 * @param mbd bean的bean定义
	 * @return bean实例(可能为null)
	 * @since 6.0.7
	 */
	@Nullable
	protected Object obtainInstanceFromSupplier(Supplier<?> supplier, String beanName, RootBeanDefinition mbd)
			throws Exception {
 
		if (supplier instanceof ThrowingSupplier<?> throwingSupplier) {
			return throwingSupplier.getWithException();
		}
		return supplier.get();
	}

 然后调用initBeanWrapper函数初始化Bean封装器,这个函数用于初始化给定的PropertyEditorRegistry对象,注册已经与该BeanFactory对象关联的自定义编辑器。源码如下:

/**
 * 使用该工厂已注册的自定义编辑器初始化给定的BeanWrapper。
 * 用于为将创建和填充bean实例的BeanWrappers。
 * <p>默认实现委托给{@link #registerCustomEditors}方法。
 * 可在子类中重写。
 * @param bw 要初始化的BeanWrapper
 */
protected void initBeanWrapper(BeanWrapper bw) {
    bw.setConversionService(getConversionService());
    registerCustomEditors(bw);
}
 
	/**
	 * 用已注册到该BeanFactory中的自定义编辑器初始化给定的PropertyEditorRegistry。
	 * <p>用于初始化和填充bean实例的BeanWrapper以及用于构造参数和工厂方法类型转换的SimpleTypeConverter。
	 * @param registry 要初始化的PropertyEditorRegistry
	 */
	protected void registerCustomEditors(PropertyEditorRegistry registry) {
	    if (registry instanceof PropertyEditorRegistrySupport registrySupport) {
	        registrySupport.useConfigValueEditors();
	    }
	    if (!this.propertyEditorRegistrars.isEmpty()) {
	        for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {
	            try {
	                registrar.registerCustomEditors(registry);
	            }
	            catch (BeanCreationException ex) {
	                Throwable rootCause = ex.getMostSpecificCause();
	                if (rootCause instanceof BeanCurrentlyInCreationException bce) {
	                    String bceBeanName = bce.getBeanName();
	                    if (bceBeanName != null && isCurrentlyInCreation(bceBeanName)) {
	                        if (logger.isDebugEnabled()) {
	                            logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() +
	                                       "] 失败,因为它尝试获取目前正在创建的bean '" +
	                                       ex.getBeanName() + "': " + ex.getMessage());
	                        }
	                        onSuppressedException(ex);
	                        continue;
	                    }
	                }
	                throw ex;
	            }
	        }
	    }
	    if (!this.customEditors.isEmpty()) {
	        this.customEditors.forEach((requiredType, editorClass) ->
	            registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass)));
	    }
	}

2、如果在RootBeanDefinition中存在factoryMethodName属性,或者说在配置文件中配置了factory-method,那么Spring会尝试使用instantiateUsingFactoryMethod(beanName, mbd, args)方法根据RootBeanDefinition中的配置生成bean的实例。源码如下:
	/**
	 * 使用命名的工厂方法实例化bean。该方法可以是静态的,如果mbd参数指定的是一个类,而不是工厂对象的类,
	 * 或者是工厂对象本身的实例变量,它们自身是使用依赖注入配置的。
	 * @param beanName bean的名称
	 * @param mbd bean定义
	 * @param explicitArgs 通过getBean方法程序化传递的参数值,如果为null,则意味着使用bean定义中的构造函数参数值
	 * @return 一个BeanWrapper实例
	 * @see #getBean(String, Object[])
	 */
	protected BeanWrapper instantiateUsingFactoryMethod(
	        String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
 
	    return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
	}

该函数用于通过调用工厂方法来实例化一个bean。该方法可以是静态的,也可以是实例变量,取决于传入的bean定义。返回一个用于新实例的BeanWrapper对象。进一步的进入ConstructorResolver对象的instantiateUsingFactoryMethod函数,源码如下:

	/**
	 * 使用命名工厂方法实例化bean。如果bean定义参数指定了类,则可以是静态的,如果是指定的“工厂bean”参数,
	 * 或者在工厂对象本身上配置使用依赖注入,而不是在构造函数参数上使用依赖注入。
	 * <p>需要迭代静态或实例方法,名称在RootBeanDefinition中指定(方法可以重载)并尝试与参数匹配。
	 * 我们没有参数类型的引用,所以只能尝试错误和尝试的方式。explicitArgs数组可以包含在对应的getBean方法中传递的参数值。
	 * @param beanName bean的名称
	 * @param mbd bean定义的合并版本
	 * @param explicitArgs 通过getBean方法传递的参数值(或者为null,->使用构造函数参数值从bean定义)
	 * @return 用于新实例的BeanWrapper
	 */
	public BeanWrapper instantiateUsingFactoryMethod(
			String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
 
		BeanWrapperImpl bw = new BeanWrapperImpl();
		this.beanFactory.initBeanWrapper(bw);
 
		Object factoryBean;
		Class<?> factoryClass;
		boolean isStatic;
 
		String factoryBeanName = mbd.getFactoryBeanName();
		if (factoryBeanName != null) {
			if (factoryBeanName.equals(beanName)) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
						"factory-bean引用指回了相同的bean定义");
			}
			factoryBean = this.beanFactory.getBean(factoryBeanName);
			if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
				throw new ImplicitlyAppearedSingletonException();
			}
			this.beanFactory.registerDependentBean(factoryBeanName, beanName);
			factoryClass = factoryBean.getClass();
			isStatic = false;
		}
		else {
			// 是一个静态工厂方法在bean类上。
			if (!mbd.hasBeanClass()) {
				throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
						"bean定义既没有bean类也没有factory-bean引用");
			}
			factoryBean = null;
			factoryClass = mbd.getBeanClass();
			isStatic = true;
		}
 
		Method factoryMethodToUse = null;
		ArgumentsHolder argsHolderToUse = null;
		Object[] argsToUse = null;
 
		if (explicitArgs != null) {
			argsToUse = explicitArgs;
		}
		else {
			Object[] argsToResolve = null;
			synchronized (mbd.constructorArgumentLock) {
				factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
				if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
					// 从缓存中找到已缓存的工厂方法...
					argsToUse = mbd.resolvedConstructorArguments;
					if (argsToUse == null) {
						argsToResolve = mbd.preparedConstructorArguments;
					}
				}
			}
			if (argsToResolve != null) {
				argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
			}
		}
 
		if (factoryMethodToUse == null || argsToUse == null) {
			// 需要确定工厂方法...
			// 尝试所有同名的方法来确定它们是否匹配给定的参数。
			factoryClass = ClassUtils.getUserClass(factoryClass);
 
			List<Method> candidates = null;
			if (mbd.isFactoryMethodUnique) {
				if (factoryMethodToUse == null) {
					factoryMethodToUse = mbd.getResolvedFactoryMethod();
				}
				if (factoryMethodToUse != null) {
					candidates = Collections.singletonList(factoryMethodToUse);
				}
			}
			if (candidates == null) {
				candidates = new ArrayList<>();
				Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
				for (Method candidate : rawCandidates) {
					if ((!isStatic || isStaticCandidate(candidate, factoryClass)) && mbd.isFactoryMethod(candidate)) {
						candidates.add(candidate);
					}
				}
			}
 
			if (candidates.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
				Method uniqueCandidate = candidates.get(0);
				if (uniqueCandidate.getParameterCount() == 0) {
					mbd.factoryMethodToIntrospect = uniqueCandidate;
					synchronized (mbd.constructorArgumentLock) {
						mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
						mbd.constructorArgumentsResolved = true;
						mbd.resolvedConstructorArguments = EMPTY_ARGS;
					}
					bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
					return bw;
				}
			}
 
			if (candidates.size() > 1) {  // 具有可忽略的单例List<?>。
				candidates.sort(AutowireUtils.EXECUTABLE_COMPARATOR);
			}
 
			ConstructorArgumentValues resolvedValues = null;
			boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
			int minTypeDiffWeight = Integer.MAX_VALUE;
			Set<Method> ambiguousFactoryMethods = null;
 
			int minNrOfArgs;
			if (explicitArgs != null) {
				minNrOfArgs = explicitArgs.length;
			}
			else {
				// 我们没有在构造函数参数中解析值,因此需要解析在bean定义中指定的构造函数参数。
				if (mbd.hasConstructorArgumentValues()) {
					ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
					resolvedValues = new ConstructorArgumentValues();
					minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
				}
				else {
					minNrOfArgs = 0;
				}
			}
 
			Deque<UnsatisfiedDependencyException> causes = null;
 
			for (Method candidate : candidates) {
				int parameterCount = candidate.getParameterCount();
 
				if (parameterCount >= minNrOfArgs) {
					ArgumentsHolder argsHolder;
 
					Class<?>[] paramTypes = candidate.getParameterTypes();
					if (explicitArgs != null) {
						// 显式参数给定了->参数数量必须完全匹配。
						if (paramTypes.length != explicitArgs.length) {
							continue;
						}
						argsHolder = new ArgumentsHolder(explicitArgs);
					}
					else {
						// 解析构造函数参数:类型转换和/或自动注入必要的。
						try {
							String[] paramNames = null;
							if (resolvedValues != null && resolvedValues.containsNamedArgument()) {
								ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
								if (pnd != null) {
									paramNames = pnd.getParameterNames(candidate);
								}
							}
							argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
									paramTypes, paramNames, candidate, autowiring, candidates.size() == 1);
						}
						catch (UnsatisfiedDependencyException ex) {
							if (logger.isTraceEnabled()) {
								logger.trace("忽略工厂方法 [" + candidate + "] of bean '" + beanName + "': " + ex);
							}
							// 忽略并尝试下一个重载的工厂方法。
							if (causes == null) {
								causes = new ArrayDeque<>(1);
							}
							causes.add(ex);
							continue;
						}
					}
 
					int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
							argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
					// 选择此工厂方法如果它代表最接近的匹配。
					if (typeDiffWeight < minTypeDiffWeight) {
						factoryMethodToUse = candidate;
						argsHolderToUse = argsHolder;
						argsToUse = argsHolder.arguments;
						minTypeDiffWeight = typeDiffWeight;
						ambiguousFactoryMethods = null;
					}
					// 找出重载的工厂方法 Ambiguity:在参数数量相同的重载工厂方法中类型差异权重相同的情况下,
					// 收集此类异常并最终引发 AmbiguousFactoryMethod 异常。
					// 然而,仅在非宽松构造函数解析模式下进行检查,并且明确忽略重载的参数签名。
					else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
							!mbd.isLenientConstructorResolution() &&
							paramTypes.length == factoryMethodToUse.getParameterCount() &&
							!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
						if (ambiguousFactoryMethods == null) {
							ambiguousFactoryMethods = new LinkedHashSet<>();
							ambiguousFactoryMethods.add(factoryMethodToUse);
						}
						ambiguousFactoryMethods.add(candidate);
					}
				}
			}
 
			if (factoryMethodToUse == null || argsToUse == null) {
				if (causes != null) {
					UnsatisfiedDependencyException ex = causes.removeLast();
					for (Exception cause : causes) {
						this.beanFactory.onSuppressedException(cause);
					}
					throw ex;
				}
				List<String> argTypes = new ArrayList<>(minNrOfArgs);
				if (explicitArgs != null) {
					for (Object arg : explicitArgs) {
						argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
					}
				}
				else if (resolvedValues != null) {
					Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
					valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
					valueHolders.addAll(resolvedValues.getGenericArgumentValues());
					for (ValueHolder value : valueHolders) {
						String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
								(value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
						argTypes.add(argType);
					}
				}
				String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"No matching factory method found on class [" + factoryClass.getName() + "]: " +
						(mbd.getFactoryBeanName() != null ?
								"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
						"factory method '" + mbd.getFactoryMethodName() + "'(" + argDesc + ")
3、解析构造函数并进行构造函数的实例化。因为一个bean对应的类中可能会有多个构造函数,而每个构造函数的参数不同,Spring在根据参数及类型去判断最终会使用哪个构造函数进行实例化。判断的过程是个比较耗时的过程,所以采用缓存机制。

autowireConstructor 方法

对于实例化的创建Spring中分成了两种情况,一个是通用的实例化,另一种是带有参数的实例化。带有参数的实例化过程相当复杂,因为存在着不确定性,所以在判断对应的参数上做了大量的工作。

	/**
	 * "自动注入构造函数" (通过类型进行构造函数参数) 行为。
	 * 如果显式构造函数参数值被指定,匹配剩余参数与 bean 工厂中的 bean。
	 * <p>这对应于构造函数注入:在这种模式下,Spring bean 工厂能够托管期望通过构造函数进行依赖解析的组件。
	 * @param beanName bean 的名称
	 * @param mbd bean 的 bean 定义
	 * @param ctors 选择的候选构造函数
	 * @param explicitArgs 通过 getBean 方法程序上传递的参数值,如果为 null(意味着使用 bean 定义中的构造函数参数值)
	 * @return 用于新实例的 BeanWrapper
	 */
	protected BeanWrapper autowireConstructor(
			String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
 
		return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
	}

该函数是用于自动注入构造函数参数的依赖项,通过使用Spring的Bean工厂来实现。它接受bean的名称、bean的定义、候选构造函数和显式参数值,并返回一个用于新实例的BeanWrapper对象。ConstructorResolver对象的autowireConstructor函数源码如下:

/**
 * "autowire constructor" (with constructor arguments by type)行为。
 * 如果显式构造函数参数值已指定,将与 bean factory 中的 bean 进行匹配,
 * 以满足所有剩余参数(-> 使用构造函数参数值而不是bean定义中的参数值)。
 * <p>这对应于构造函数注入:在该模式下,Spring bean factory 能够托管期望基于依赖解析的构造函数参数的组件。
 * @param beanName bean 的名称
 * @param mbd 合并的bean定义
 * @param chosenCtors 选择的候选项构造函数(如果找不到则为null)
 * @param explicitArgs 通过getBean方法传递的显式参数值(如果未解析构造函数参数值则为null)
 * @return 一个新的实例的BeanWrapper
 */
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
                                       @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
 
    BeanWrapperImpl bw = new BeanWrapperImpl();
    this.beanFactory.initBeanWrapper(bw);
 
    Constructor<?> constructorToUse = null;
    ArgumentsHolder argsHolderToUse = null;
    Object[] argsToUse = null;
 
    // explicitArgs通过getBean方法传入,如果getBean方法调用的时候指定方法参数那么直接使用
    if (explicitArgs != null) {
        argsToUse = explicitArgs;
    } else {
        // 如果在getBean方法时候没有指定则尝试从配置文件中解析
        Object[] argsToResolve = null;
        synchronized (mbd.constructorArgumentLock) {
            // 尝试从缓存中获取
            constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
            if (constructorToUse != null && mbd.constructorArgumentsResolved) {
                // 从缓存中找到构造函数...
                argsToUse = mbd.resolvedConstructorArguments;
                if (argsToUse == null) {
                    // 配置的构造函数参数
                    argsToResolve = mbd.preparedConstructorArguments;
                }
            }
        }
        // 如果缓存中存在
        if (argsToResolve != null) {
            // 解析参数类型,如给定方法的构造函数A(int,int)则通过此方法后就会把配置中的
            // ("1","1")转换为(1,1)。缓存中的值可能是原始值,也可能是最终值
            argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
        }
    }
 
    // 没有被缓存
    if (constructorToUse == null || argsToUse == null) {
        // 寻找指定的构造函数,如果有的话。
        Constructor<?>[] candidates = chosenCtors;
        if (candidates == null) {
            Class<?> beanClass = mbd.getBeanClass();
            try {
                candidates = (mbd.isNonPublicAccessAllowed() ?
                        beanClass.getDeclaredConstructors() : beanClass.getConstructors());
            } catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Resolution of declared constructors on bean Class [" + beanClass.getName() +
                                "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
            }
        }
 
        if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
            // 如果构造函数只有一个,预期的参数为空,RootBeanDefinition没有带参数的构造函数
            Constructor<?> uniqueCandidate = candidates[0];
            if (uniqueCandidate.getParameterCount() == 0) {
                // 指定Bean的构造函数是无参构造函数
                synchronized (mbd.constructorArgumentLock) {
                    // 则直接将构造函数信息保存到RootBeanDefinition中,这样便于后续使用
                    mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
                    mbd.constructorArgumentsResolved = true;
                    mbd.resolvedConstructorArguments = EMPTY_ARGS;
                }
 
                // 调用instantiate函数来创建Bean实例
                bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
                return bw;
            }
        }
 
        // 需要解析构造函数。
        boolean autowiring = (chosenCtors != null ||
                mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
        ConstructorArgumentValues resolvedValues = null;
 
        int minNrOfArgs;
        if (explicitArgs != null) {
            minNrOfArgs = explicitArgs.length;
        } else {
            // 从RootBeanDefinition提取配置文件中配置的构造函数的参数信息
            ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
 
            // 用于承载解析后的构造函数的参数值
            resolvedValues = new ConstructorArgumentValues();
 
            // 解析构造函数的参数,并返回参数的个数
            minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
        }
 
        // 排序给定的构造函数,public构造函数优先参数数量降序,
        // 非public构造函数参数数量降序
        AutowireUtils.sortConstructors(candidates);
        int minTypeDiffWeight = Integer.MAX_VALUE;
        Set<Constructor<?>> ambiguousConstructors = null;
        Deque<UnsatisfiedDependencyException> causes = null;
 
        for (Constructor<?> candidate : candidates) {
            int parameterCount = candidate.getParameterCount();
 
            if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
                // 如果已经找到选用的构造函数或者需要的参数个数小于当前的构造函数
                // 参数个数则终止,因为已经按照参数的个数进行降序排序了。
                break;
            }
            if (parameterCount < minNrOfArgs) {
                // 当前构造函数的参数个数小于参数的个数
                continue;
            }
 
            ArgumentsHolder argsHolder;
            Class<?>[] paramTypes = candidate.getParameterTypes();
            if (resolvedValues != null) {
                // 有参数则根据值构造对应参数类型的参数
                try {
                    String[] paramNames = null;
                    if (resolvedValues.containsNamedArgument()) {
                        // 注释上获取参数名称
                        paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
                        if (paramNames == null) {
                            // 获取参数名称探索期
                            ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                            if (pnd != null) {
                                // 获取指定构造函数的参数名称
                                paramNames = pnd.getParameterNames(candidate);
                            }
                        }
                    }
                    // 根据名称和数据类型创建参数持有者
                    argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
                            getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
                } catch (UnsatisfiedDependencyException ex) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
                    }
                    // 忽略并尝试下一个构造函数。
                    if (causes == null) {
                        causes = new ArrayDeque<>(1);
                    }
                    causes.add(ex);
                    continue;
                }
            } else {
                // 显式参数已给出 -> 参数数量必须完全匹配。
                if (parameterCount != explicitArgs.length) {
                    continue;
                }
                // 构造函数没有参数的情况
                argsHolder = new ArgumentsHolder(explicitArgs);
            }
 
            // 探测是否有不确定性的构造函数存在,例如不同构造函数的参数为父子关系
            int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
                    argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
            // 选择此构造函数如果它表示最接近匹配的构造函数。
            if (typeDiffWeight < minTypeDiffWeight) {
                constructorToUse = candidate;
                argsHolderToUse = argsHolder;
                argsToUse = argsHolder.arguments;
                minTypeDiffWeight = typeDiffWeight;
                ambiguousConstructors = null;
            } else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
                if (ambiguousConstructors == null) {
                    ambiguousConstructors = new LinkedHashSet<>();
                    ambiguousConstructors.add(constructorToUse);
                }
                ambiguousConstructors.add(candidate);
            }
        }
 
        if (constructorToUse == null) {
            if (causes != null) {
                UnsatisfiedDependencyException ex = causes.removeLast();
                for (Exception cause : causes) {
                    this.beanFactory.onSuppressedException(cause);
                }
                throw ex;
            }
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Could not resolve matching constructor on bean class [" + mbd.getBeanClassName() + "] " +
                    "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities. " +
                    "You should also check the consistency of arguments when mixing indexed and named arguments, " +
                    "especially in case of bean definition inheritance)");
        } else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Ambiguous constructor matches found on bean class [" + mbd.getBeanClassName() + "] " +
                    "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
                    ambiguousConstructors);
        }
 
        if (explicitArgs == null && argsHolderToUse != null) {
            // 将解析的构造函数加入缓存
            argsHolderToUse.storeCache(mbd, constructorToUse);
        }
    }
 
    Assert.state(argsToUse != null, "Unresolved constructor arguments");
 
    // 将构建的实例加入到BeanWrapper中
    bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
    return bw;
}

 这个函数是用于自动装配Java类的构造函数的。它根据指定的bean名称、合并的bean定义、选择的构造函数参数类型和其他显式参数值来返回一个BeanWrapper。在函数中,它根据bean的构造函数参数类型进行自动装配,如果存在显式参数值,则使用显式参数值替代构造函数参数值。最后,它根据选择的构造函数和参数值创建一个BeanWrapper实例并返回

 大致概括一下整个protected BeanWrapper autowireConstructor方法

1、构造函数参数的确定。

1、根据explicitArgs参数判断,如果传入的参数explicitArgs不为空,那么可以直接确定参数,因为explicitArgs参数在调用Bean的时候用户指定的。在BeanFactory类中存在这样的方法:Object getBean(String name, Object... args) throws BeansException;在获取Bean的时候,用户不仅可以指定Bean的名称还可以指定Bean所对应类的构造函数或者工厂方法参数,主要用于静态工厂方法的调用,而这里是需要给定完全匹配的参数的,所以,便可以判断,如果传入参数explicitArgs不为空,则可以确定构造函数参数就是它。
2、缓存中获取,如果构造函数参数已经记录在缓存中,那么便可以直接拿来使用。缓存中的可能是参数的最终类型也可能是参数的初始类型,所以即使在缓存中得到了参数,也需要经过类型转换器的过滤,以确保参数类型与对应的构造函数的参数类型完全一致。
3、配置文件获取,分析从获取配置文件中配置的构造函数信息开始,经过之前的分析可知,Spring的配置文件中的信息经过转换都会通过BeanDefinition实现承载,也就是参数mbd中包含,那么可以通过mbd.getConstructorArgumentValues()来获取配置的构造函数信息。

其中源码如下

    ArgumentsHolder argsHolderToUse = null;
    Object[] argsToUse = null;
 
    // explicitArgs通过getBean方法传入,如果getBean方法调用的时候指定方法参数那么直接使用
    if (explicitArgs != null) {
        argsToUse = explicitArgs;
    } else {
        // 如果在getBean方法时候没有指定则尝试从配置文件中解析
        Object[] argsToResolve = null;
        synchronized (mbd.constructorArgumentLock) {
            // 尝试从缓存中获取
            constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
            if (constructorToUse != null && mbd.constructorArgumentsResolved) {
                // 从缓存中找到构造函数...
                argsToUse = mbd.resolvedConstructorArguments;
                if (argsToUse == null) {
                    // 配置的构造函数参数
                    argsToResolve = mbd.preparedConstructorArguments;
                }
            }
        }
        // 如果缓存中存在
        if (argsToResolve != null) {
            // 解析参数类型,如给定方法的构造函数A(int,int)则通过此方法后就会把配置中的
            // ("1","1")转换为(1,1)。缓存中的值可能是原始值,也可能是最终值
            argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
        }
    }

 2、构造函数的确定

经过第一步后已经确定了构造函数的参数,首先第一步就是获取所有的构造函数,源码如下:

        // 寻找指定的构造函数,如果有的话。
        Constructor<?>[] candidates = chosenCtors;
        if (candidates == null) {
            Class<?> beanClass = mbd.getBeanClass();
            try {
                candidates = (mbd.isNonPublicAccessAllowed() ?
                        beanClass.getDeclaredConstructors() : beanClass.getConstructors());
            } catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Resolution of declared constructors on bean Class [" + beanClass.getName() +
                                "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
            }
        }

接下来的任务就是根据构造函数参数在所有构造函数中锁定对应的构造函数,如果构造函数只有一个,且传入的参数为空,RootBeanDefinition中配置的构造函数的参数也为空,那么直接使用无参构造函数进行构造就可以了,源码如下

        if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
            // 如果构造函数只有一个,预期的参数为空,RootBeanDefinition没有带参数的构造函数
            Constructor<?> uniqueCandidate = candidates[0];
            if (uniqueCandidate.getParameterCount() == 0) {
                // 指定Bean的构造函数是无参构造函数
                synchronized (mbd.constructorArgumentLock) {
                    // 则直接将构造函数信息保存到RootBeanDefinition中,这样便于后续使用
                    mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
                    mbd.constructorArgumentsResolved = true;
                    mbd.resolvedConstructorArguments = EMPTY_ARGS;
                }
 
                // 调用instantiate函数来创建Bean实例
                bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
                return bw;
            }
        }

如果构造函数有多个或者构造函数的参数不为空,则需要根据参数、参数值、构造函数来确定对应的构造函数了,不然可能会存在构造函数的参数与传入的参数不一致导致构建Bean实例失败的问题。

如果传入的参数explicitArgs不为空,那么可以直接确定参数,匹配构造函数的时候直接使用explicitArgs就可以了,否则需要通过mbd.getConstructorArgumentValues()来获取配置的构造函数信息,然后解析构造函数的参数信息,源码如下:

        ConstructorArgumentValues resolvedValues = null;
 
        int minNrOfArgs;
        if (explicitArgs != null) {
            minNrOfArgs = explicitArgs.length;
        } else {
            // 从RootBeanDefinition提取配置文件中配置的构造函数的参数信息
            ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
 
            // 用于承载解析后的构造函数的参数值
            resolvedValues = new ConstructorArgumentValues();
 
            // 解析构造函数的参数,并返回参数的个数
            minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
        }

上面的代码,主要是调用resolveConstructorArguments函数解析构造函数构造函数的参数,使用类型转换器将RootBeanDefinition中配置的构造函数的参数值解析成正确的类型,并写入到resolvedValues中以供后面使用,resolveConstructorArguments源码如下:

	/**
	 * 将bean的构造函数参数解析为resolvedValues对象。
	 * 这可能涉及到查找其他bean。
	 * <p>此外,此方法还用于处理对静态工厂方法的调用。
	 */
	private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
			ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
 
		TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
		TypeConverter converter = (customConverter != null ? customConverter : bw);
		BeanDefinitionValueResolver valueResolver =
				new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
 
		int minNrOfArgs = cargs.getArgumentCount();
 
		for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
			int index = entry.getKey();
			if (index < 0) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Invalid constructor argument index: " + index);
			}
			if (index + 1 > minNrOfArgs) {
				minNrOfArgs = index + 1;
			}
			ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
			if (valueHolder.isConverted()) {
				resolvedValues.addIndexedArgumentValue(index, valueHolder);
			}
			else {
				Object resolvedValue =
						valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
				ConstructorArgumentValues.ValueHolder resolvedValueHolder =
						new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
				resolvedValueHolder.setSource(valueHolder);
				resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
			}
		}
 
		for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
			if (valueHolder.isConverted()) {
				resolvedValues.addGenericArgumentValue(valueHolder);
			}
			else {
				Object resolvedValue =
						valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
				ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(
						resolvedValue, valueHolder.getType(), valueHolder.getName());
				resolvedValueHolder.setSource(valueHolder);
				resolvedValues.addGenericArgumentValue(resolvedValueHolder);
			}
		}
 
		return minNrOfArgs;
	}

该函数用于将 bean 的构造函数参数解析为 resolvedValues 对象,可能需要查找其他 bean。如果参数值是通过静态工厂方法传递的,该方法也会被调用。函数会使用 TypeConverter 将参数值转换为正确的类型,并将其添加到 resolvedValues 中。其中转换参数值类型的操作是在BeanDefinitionValueResolver类的Object resolveValueIfNecessary(Object argName, @Nullable Object value)函数中实现的,具体的代码逻辑不再做进一步的分析。

而匹配构造函数的方法就是根据构造函数的个数进行匹配,所以在匹配之前需要先对构造函数按照public构造函数优先参数数量降序、非public构造函数参数降序。源码如下:

        // 排序给定的构造函数,public构造函数优先参数数量降序,
        // 非public构造函数参数数量降序
        AutowireUtils.sortConstructors(candidates);

这样可以在遍历的情况下迅速判断排在后面的构造函数参数个数是否符合条件。

由于在配置文件中并不是唯一限制使用参数位置索引的方式去创建,同样还支持指定参数名称进行设定参数值的情况,如<constructor-arg name="aa">,那么这种情况就需要首先确定构造函数中的参数名称。源码如下:

        int minTypeDiffWeight = Integer.MAX_VALUE;
        Set<Constructor<?>> ambiguousConstructors = null;
        Deque<UnsatisfiedDependencyException> causes = null;
 
        for (Constructor<?> candidate : candidates) {
            int parameterCount = candidate.getParameterCount();
 
            if (constructorToUse != null && argsToUse != null && 
                argsToUse.length > parameterCount) {
                // 如果已经找到选用的构造函数或者需要的参数个数小于当前的构造函数
                // 参数个数则终止,因为已经按照参数的个数进行降序排序了。
                break;
            }
            if (parameterCount < minNrOfArgs) {
                // 当前构造函数的参数个数小于参数的个数
                continue;
            }
 
            ArgumentsHolder argsHolder;
            Class<?>[] paramTypes = candidate.getParameterTypes();
            if (resolvedValues != null) {
                // 有参数则根据值构造对应参数类型的参数
                String[] paramNames = null;
                if (resolvedValues.containsNamedArgument()) {
                    // 注释上获取参数名称
                    paramNames = ConstructorPropertiesChecker
                        .evaluate(candidate, parameterCount);
                    if (paramNames == null) {
                        // 获取参数名称探索期
                        ParameterNameDiscoverer pnd = this.beanFactory
                            .getParameterNameDiscoverer();
                        if (pnd != null) {
                            // 获取指定构造函数的参数名称
                            paramNames = pnd.getParameterNames(candidate);
                        }
                    }
                }
                // 根据名称和数据类型创建参数持有者
                argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw
                    , paramTypes, paramNames, getUserDeclaredConstructor(candidate)
                    , autowiring, candidates.length == 1);
            } else {
                // 显式参数已给出 -> 参数数量必须完全匹配。
                if (parameterCount != explicitArgs.length) {
                    continue;
                }
                // 构造函数没有参数的情况
                argsHolder = new ArgumentsHolder(explicitArgs);
            }
 
            // 探测是否有不确定性的构造函数存在,例如不同构造函数的参数为父子关系
            int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
                    argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
            // 选择此构造函数如果它表示最接近匹配的构造函数。
            if (typeDiffWeight < minTypeDiffWeight) {
                constructorToUse = candidate;
                argsHolderToUse = argsHolder;
                argsToUse = argsHolder.arguments;
                minTypeDiffWeight = typeDiffWeight;
                ambiguousConstructors = null;
            } else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
                if (ambiguousConstructors == null) {
                    ambiguousConstructors = new LinkedHashSet<>();
                    ambiguousConstructors.add(constructorToUse);
                }
                ambiguousConstructors.add(candidate);
            }
        }

上面的代码首先是针对构造函数中的参数个数与传入的参数个数或RootBeanDefinition中配置构造函数的参数个数进行比较,针对不一致的就继续遍历构造函数或跳出循环;如果传入的参数explicitArgs不为空则使用explicitArgs构建ArgumentsHolder,否则需要根据上面解析出来的参数值resolvedValues构建ArgumentsHolder。

使用resolvedValues构建ArgumentsHolder时,如果有参数已经定义了相应的参数名称,则需要从构造函数中获取参数的名称。获取参数名称可以有两种方式,一种是通过注解的方式直接获取,另一种就是使用Spring中提供的工具类ParameterNameDiscoverer来获取。构造函数、参数名称、参数类型、参数值都确定后就可以锁定构造函数以及转换对应的参数类型了。

3、根据确定的构造函数转换对应的参数类型 

主要是使用Spring中提供的类型转换器或者用户提供的自定义类型转换器进行转换 。源码如下:

// 根据名称和数据类型创建参数持有者
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames
    , getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);

其中Constructor<?> getUserDeclaredConstructor(Constructor<?> constructor)用于获取用户自定义的构造函数,由于传入的构造函数有可能是CGLIB生成的子类,所以需要找到真正的构造函数。createArgumentArray会根据确定的构造函数转换对应的参数类型,相应的源码如下:

	/**
	 * 根据已解析的构造函数或工厂方法的参数值创建一个参数数组。
	 */
	private ArgumentsHolder createArgumentArray(
			String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,
			BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,
			boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException {
 
	    TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
	    TypeConverter converter = (customConverter != null ? customConverter : bw);
 
	    ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
	    Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
	    Set<String> allAutowiredBeanNames = new LinkedHashSet<>(paramTypes.length * 2);
 
	    for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
	        Class<?> paramType = paramTypes[paramIndex];
	        String paramName = (paramNames != null ? paramNames[paramIndex] : "");
	        // 尝试找到匹配的构造函数参数值,可以是索引参数或泛型参数。
	        ConstructorArgumentValues.ValueHolder valueHolder = null;
	        if (resolvedValues != null) {
	            valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
	            // 如果我们无法直接匹配,并且不需要自动装配,
	            // 那么尝试下一个通用的、未分组的参数值作为回退:
	            // 它可以在类型转换后匹配(例如,String -> int)。
	            if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
	                valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
	            }
	        }
	        if (valueHolder != null) {
	            // 我们找到了一个可能的匹配项 - 让我们尝试一下。
	            // 不要重复考虑相同的值定义!
	            usedValueHolders.add(valueHolder);
	            Object originalValue = valueHolder.getValue();
	            Object convertedValue;
	            if (valueHolder.isConverted()) {
	                convertedValue = valueHolder.getConvertedValue();
	                args.preparedArguments[paramIndex] = convertedValue;
	            }
	            else {
	                MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
	                try {
	                    convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
	                }
	                catch (TypeMismatchException ex) {
	                    throw new UnsatisfiedDependencyException(
	                            mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
	                            "无法将参数值的类型 [" +
	                            ObjectUtils.nullSafeClassName(valueHolder.getValue()) +
	                            "] 转换为所需类型 [" + paramType.getName() + "]: " + ex.getMessage());
	                }
	                Object sourceHolder = valueHolder.getSource();
	                if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder constructorValueHolder) {
	                    Object sourceValue = constructorValueHolder.getValue();
	                    args.resolveNecessary = true;
	                    args.preparedArguments[paramIndex] = sourceValue;
	                }
	            }
	            args.arguments[paramIndex] = convertedValue;
	            args.rawArguments[paramIndex] = originalValue;
	        }
	        else {
	            MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
	            // 没有找到明确的匹配项:我们要么需要自动装配,要么在给定构造函数的情况下无法创建参数数组。
	            if (!autowiring) {
	                throw new UnsatisfiedDependencyException(
	                        mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
	                        "对于类型 [" + paramType.getName() +
	                        "] 的参数找到冲突的参数值 - 您是否将正确的 bean 引用作为参数指定了?");
	            }
	            try {
	                ConstructorDependencyDescriptor desc = new ConstructorDependencyDescriptor(methodParam, true);
	                Set<String> autowiredBeanNames = new LinkedHashSet<>(2);
	                Object arg = resolveAutowiredArgument(
	                        desc, paramType, beanName, autowiredBeanNames, converter, fallback);
	                if (arg != null) {
	                    setShortcutIfPossible(desc, paramType, autowiredBeanNames);
	                }
	                allAutowiredBeanNames.addAll(autowiredBeanNames);
	                args.rawArguments[paramIndex] = arg;
	                args.arguments[paramIndex] = arg;
	                args.preparedArguments[paramIndex] = desc;
	                args.resolveNecessary = true;
	            }
	            catch (BeansException ex) {
	                throw new UnsatisfiedDependencyException(
	                        mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
	            }
	        }
	    }
 
	    registerDependentBeans(executable, beanName, allAutowiredBeanNames);
 
	    return args;
	}

4、构造函数不确定的验证

即使构造函数、参数名称、参数类型、参数值都确定后、也不一定会直接锁定构造函数,不同构造函数的参数为父子关系,所以Spring在最后又做了一次验证。

5、根据实例化策略以及得到的构造函数及构造函数参数实例化Bean 

生成Bean实例的代码是在函数instantiate中实现的,源码如下:

/**
 * 使用给定的参数实例化对象。
 *
 * @param beanName 被实例化bean的名称
 * @param mbd 根bean定义
 * @param constructorToUse 被使用的构造函数
 * @param argsToUse 构造函数参数值
 * @return 实例化后的对象
 * @throws Throwable 如果实例化失败,则抛出异常
 */
private Object instantiate(String beanName, RootBeanDefinition mbd, Constructor<?> constructorToUse, Object[] argsToUse) {
    try {
        // 获取实例化策略
        InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy();
        // 使用实例化策略进行实例化
        return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
    }
    catch (Throwable ex) {
        // 如果实例化失败,则抛出异常
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, ex.getMessage(), ex);
    }
}

这个函数用于实例化一个bean对象。它首先获取BeanFactory的 InstantiationStrategy策略,然后调用 InstantiationStrategy 的 instantiate 方法来实例化对象。如果发生异常,会抛出一个 BeanCreationException 异常。

4、实例策略

 InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy();中InstantiationStrategy有两个实现类,SimpleInstantiationStrategy是其中一个,SimpleInstantiationStrategy的 instantiate方法的源码如下:

	/**
	 * 根据给定的参数实例化Bean对象
	 * 
	 * @param bd 实例化的Bean对象的定义
	 * @param beanName 实例化的Bean对象的名称
	 * @param owner 实例化的Bean对象所在的工厂
	 * @param ctor 构造方法
	 * @param args 构造方法的参数
	 * @return 实例化的Bean对象
	 */
	@Override
	public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
			final Constructor<?> ctor, Object... args) {
 
		// 如果有需要覆盖或者动态替换的方法则当然需要使用cglib进行动态代理,
        // 因为可以在创建代理的同时将动态方法织入类中。但是如果没有需要动态
        // 改变得方法,为了方便直接反射就可以了。
		if (!bd.hasMethodOverrides()) {
			return BeanUtils.instantiateClass(ctor, args);
		}
		else {
			// 否则,调用instantiateWithMethodInjection方法进行实例化
			return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
		}
	}

这个Java函数是一个重写的方法,当RootBeanDefinition没有方法覆盖时,使用BeanUtils类的instantiateClass方法创建对象;否则,调用instantiateWithMethodInjection方法进行构造函数注入并创建对象。其中BeanUtils类的instantiateClass方法源码如下:

	/**
	 * 方便的方法使用给定的构造函数实例化一个类。
	 * <p>请注意,如果给定不访问(即不公开)的构造函数,此方法将尝试设置构造函数的访问权限,
	 * 并支持带有可选参数和默认值的 Kotlin 类。
	 * @param ctor 要实例化的构造函数
	 * @param args 要应用的构造函数参数(对于未指定的参数使用 {@code null},Kotlin 可选参数和 Java 基本类型被支持)
	 * @return 新的实例
	 * @throws BeanInstantiationException 如果无法实例化 Bean
	 * @see Constructor#newInstance
	 */
	public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
	    Assert.notNull(ctor, "构造函数不能为空");
	    try {
	        ReflectionUtils.makeAccessible(ctor);
	        if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
	            return KotlinDelegate.instantiateClass(ctor, args);
	        }
	        else {
	            int parameterCount = ctor.getParameterCount();
	            Assert.isTrue(args.length <= parameterCount, "不能指定比构造函数参数更多的参数");
	            if (parameterCount == 0) {
	                return ctor.newInstance();
	            }
	            Class<?>[] parameterTypes = ctor.getParameterTypes();
	            Object[] argsWithDefaultValues = new Object[args.length];
	            for (int i = 0 ; i < args.length; i++) {
	                if (args[i] == null) {
	                    Class<?> parameterType = parameterTypes[i];
	                    argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
	                }
	                else {
	                    argsWithDefaultValues[i] = args[i];
	                }
	            }
	            return ctor.newInstance(argsWithDefaultValues);
	        }
	    }
	    catch (InstantiationException ex) {
	        throw new BeanInstantiationException(ctor, "它是抽象类吗?", ex);
	    }
	    catch (IllegalAccessException ex) {
	        throw new BeanInstantiationException(ctor, "构造函数可访问吗?", ex);
	    }
	    catch (IllegalArgumentException ex) {
	        throw new BeanInstantiationException(ctor, "构造函数的参数不合法", ex);
	    }
	    catch (InvocationTargetException ex) {
	        throw new BeanInstantiationException(ctor, "构造函数抛出异常", ex.getTargetException());
	    }
	}

 该函数是一个静态方法,用于实例化一个给定构造函数的类。它支持设置非公有构造函数的访问权限,并且在参数中支持 Kotlin 可选参数和默认值。函数的参数是一个构造函数和构造函数参数。返回值是新创建的实例对象。如果实例化失败,会抛出相应的异常。instantiateWithMethodInjection函数创建Bean实例的源码如下:

	/**
	 * 使用方法注入实例化对象
	 *
	 * @param bd         RootBeanDefinition对象
	 * @param beanName   根Bean定义的名称
	 * @param owner      Bean工厂对象
	 * @param ctor       构造函数
	 * @param args       构造函数参数
	 * @return 实例化对象
	 */
	@Override
	protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
			@Nullable Constructor<?> ctor, Object... args) {
 
		return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
	}

该函数主要是调用CglibSubclassCreator对象的instantiate函数创建Bean实例,其源码如下: 

		/**
		 * 创建一个实现所需查找功能的动态生成的子类的实例。
		 * @param ctor 要使用的构造函数。如果为 {@code null},则使用无参构造函数(无参数化或设置注入)
		 * @param args 用于构造函数的参数。如果 {@code ctor} 参数为 {@code null} 则忽略此参数
		 * @return 新的动态生成子类的实例
		 */
		public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
		    Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
		    Object instance;
		    if (ctor == null) {
		        instance = BeanUtils.instantiateClass(subclass);
		    }
		    else {
		        try {
		            Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
		            instance = enhancedSubclassConstructor.newInstance(args);
		        }
		        catch (Exception ex) {
		            throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
		                    "无法调用 CGLIB 优化子类 [" + subclass.getName() + "] 的构造函数", ex);
		        }
		    }
		    // SPR-10785:直接在实例上设置回调(而不是通过 Enhancer 在优化类中)以避免内存泄漏
		    Factory factory = (Factory) instance;
		    factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
		            new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
		            new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
		    return instance;
		}

 这个函数用于创建一个动态生成的子类的实例,该子类实现了所需的查找功能。如果传入的构造函数为null,则使用无参构造函数。函数内部首先创建一个增强的子类,然后根据传入的构造函数参数创建子类的实例。最后,将回调函数设置到实例上,并返回创建的实例。

二、提前缓存单实例,解决循环依赖

在doCreateBean函数有如下一段代码:

		// 为了能够在生命周期接口(如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");
		        // 如果logger的级别允许,输出日志:提前缓存该bean以允许解决潜在的循环引用
		    }
		    addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		    // 添加单例工厂:调用getEarlyBeanReference方法获取提前的bean引用
		}

 其中addSingletonFactory的源码如下:

	/**
	 * 添加给定的单例工厂,以便在需要时用于构建指定的单例对象。
	 * <p>可用于提前注册单例对象,例如为了解决循环引用问题。
	 * @param beanName Bean的名称
	 * @param singletonFactory 单例对象的工厂
	 */
	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);
	        }
	    }
	}

 这是一个用于添加给定的单例工厂的函数,该工厂在需要时用于构建指定的单例对象。它用于提前注册单例对象,以解决循环引用等问题。函数接受一个 bean 名称和一个单例对象工厂。函数的实现确保单例工厂不为空,并将单例工厂添加到内部数据结构中。如果该 bean 名称尚未在单例对象中注册,则将其添加到单例工厂和注册的单例对象中。其中getEarlyBeanReference的源码如下:

	/**
	 * 获取指定bean的早期引用,通常用于解决循环引用的问题。
	 * @param beanName bean的名称(用于错误处理)
	 * @param mbd 合并后的bean定义
	 * @param bean 原始的bean实例
	 * @return 返回作为bean引用暴露的对象
	 */
	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
	    Object exposedObject = bean;
	    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
	        for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
	            exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
	        }
	    }
	    return exposedObject;
	}

 这个函数用于获取指定bean的早期引用,通常用于解决循环引用的问题。如果bean的合并定义不是合成的,并且有实例化感知的Bean后处理器,那么函数会遍历后处理器列表,并逐个调用他们的getEarlyBeanReference方法,最后返回被处理的bean对象。

三、属性注入

函数populateBean主要功能是属性填充,源码如下:

/**
 * 使用给定的 Bean定义为给定的Bean实例填充属性值。
 *
 * @param beanName 被填充Bean的名称
 * @param mbd Bean定义
 * @param bw 包含Bean实例的BeanWrapper
 */
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    if (bw == null) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "无法将属性值应用于空实例");
        } else {
            // 对于空实例,跳过属性填充阶段。
            return;
        }
    }
 
    if (bw.getWrappedClass().isRecord()) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "无法将属性值应用于记录");
        } else {
            // 记录是不可变的,因此跳过属性填充阶段。
            return;
        }
    }
 
    // 在设置属性之前,给任何具有InstanceAwareBeanPostProcessor的实例机会修改Bean的状态。
    // 例如,可以用来支持字段注入的样式。
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                return;
            }
        }
    }
 
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
 
    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        // 如果适用,请基于名称自动装配 by name 添加属性值。
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        // 如果适用,请基于自动装配 by type 添加属性值。
        if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }
    if (hasInstantiationAwareBeanPostProcessors()) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
                return;
            }
            pvs = pvsToUse;
        }
    }
 
    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
    if (needsDepCheck) {
        PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        checkDependencies(beanName, mbd, filteredPds, pvs);
    }
 
    if (pvs != null) {
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

方法用于将bean定义中的属性值填充到给定的BeanWrapper中。首先检查bean实例是否为空,如果是,则跳过属性填充阶段。如果bean是记录类型,则无法对其进行属性填充(因为记录是不可变的)。然后,给定的bean后处理器机会修改bean的状态。根据bean的自动装配模式,通过名称或类型进行属性填充。最后,如果存在bean后处理器,则对其进行属性处理,并根据需要进行依赖检查和属性值应用。

大致流程为:

1、InstantiationAwareBeanPostProcessor处理器的postProcessAfterInstantiation函数的应用,可以控制程序是否继续进行属性填充。
2、根据注入类型(ByName/ByType),提取依赖的bean,并统一存入PropertyValues中。
3、应用InstantiationAwareBeanPostProcessor处理器的postProcessProperties方法,对属性获取完毕填充前对属性的再次处理。典型应用是RequiredAnnotationBeanPostProcessor类中对属性的验证。
4、将所有PropertyValues中的属性填充至BeanWrapper中。

1、autowireByName方法 

这个函数是一个Java类的方法,用于根据指定的 bean 名称,通过属性名称进行自动命名关联。如果属性值为空,则通过查找其他 bean 中的引用进行填充,并将已填充的对象注册到属性值中。如果找不到匹配的 bean,则不进行自动关联。autowireByName的源码如下:

	/**
	 * 在autowire设置为"byName"时,使用其他工厂中的bean来填充任何丢失的属性值。
	 * @param beanName 我们正在连接的bean的名称。对于调试消息很有用,但在功能上不使用。
	 * @param mbd 要通过自动连接更新的bean的定义
	 * @param bw 从中我们可以获取有关bean信息的BeanWrapper
	 * @param pvs 要注册已连接对象的属性值的PropertyValues
	 */
	protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
        // 寻找BeanWrapper中需要注入的属性
	    String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
	    for (String propertyName : propertyNames) {
	        if (containsBean(propertyName)) {
                // 递归初始化相关的Bean
	            Object bean = getBean(propertyName);
	            pvs.add(propertyName, bean);
                // 注册依赖
	            registerDependentBean(propertyName, beanName);
	            if (logger.isTraceEnabled()) {
	                logger.trace("通过名称自动连接bean名称 '" + beanName +
	                        "' 通过属性 '" + propertyName + "' 到名为 '" + propertyName + "' 的bean");
	            }
	        }
	        else {
	            if (logger.isTraceEnabled()) {
	                logger.trace("不通过名称自动连接bean '" + beanName +
	                        "' 的属性 '" + propertyName + "': 没有找到匹配的bean");
	            }
	        }
	    }
	}
2、autowireByType

该函数是一个抽象方法,用于定义按类型自动装配(bean属性按类型)的行为。它在bean工厂中寻找类型为属性类型的单个bean,并将找到的bean添加到属性值中。该函数还考虑了优先级顺序,并记录依赖关系。源码如下:

	/**
	 * 定义“按类型自动装配”(按类型自动装配属性)的行为。
	 * <p>这对于PicoContainer的默认行为类似,其中bean工厂中必须存在一种类型的一个bean。
	 * 这使得bean工厂在小的命名空间中配置简单,但在大的应用中不如标准Spring行为好。
	 * @param beanName 要按类型自动装配的bean的名称
	 * @param mbd 合并的bean定义,通过自动装配进行更新
	 * @param bw 可以从中获取有关bean信息的BeanWrapper
	 * @param pvs 要与已连接对象一起的属性值
	 */
	protected void autowireByType(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
 
		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}
        // 寻找BeanWrapper中需要依赖注入的属性
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		Set<String> autowiredBeanNames = new LinkedHashSet<>(propertyNames.length * 2);
		for (String propertyName : propertyNames) {
			try {
				PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
				// 对于类型为Object的属性,不会尝试按类型自动装配,即使它技术上是一个未满足的非简单属性。
				if (Object.class != pd.getPropertyType()) {
                    // 探测指定属性的set方法
					MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
					// 除非bean实例是PriorityOrdered类型的(优先级后处理器),
                    // 否则不要进行类型匹配的即时初始化。
					boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
					DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
					Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
					if (autowiredArgument != null) {
						pvs.add(propertyName, autowiredArgument);
					}
					for (String autowiredBeanName : autowiredBeanNames) {
						registerDependentBean(autowiredBeanName, beanName);
						if (logger.isTraceEnabled()) {
							logger.trace("按类型从bean名称 '" + beanName + "' 通过属性 '" +
									propertyName + "' 自动装配到bean名称 '" + autowiredBeanName + "'");
						}
					}
					autowiredBeanNames.clear();
				}
			}
			catch (BeansException ex) {
				throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
			}
		}
	}

对于寻找类型匹配上午逻辑实现封装在DefaultListableBeanFactory类的resolveDependency函数中,源码如下

	/**
	 * 解析依赖项并返回对象
	 * 
	 * @param descriptor 依赖描述符对象,用于描述所依赖的对象
	 * @param requestingBeanName 请求对象的名称
	 * @param autowiredBeanNames 自动注入的bean名称集合
	 * @param typeConverter 类型转换器
	 * @return 解析后的依赖对象
	 * @throws BeansException 如果解析依赖对象时发生异常,将抛出BeansException异常
	 */
	@Override
	@Nullable
	public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
 
		descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
		if (Optional.class == descriptor.getDependencyType()) {
			return createOptionalDependency(descriptor, requestingBeanName);
		}
		else if (ObjectFactory.class == descriptor.getDependencyType() ||
				ObjectProvider.class == descriptor.getDependencyType()) {
			return new DependencyObjectProvider(descriptor, requestingBeanName);
		}
		else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
			return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
		}
		else {
			Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
					descriptor, requestingBeanName);
			if (result == null) {
				result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
			}
			return result;
		}
	}

 该函数是一个依赖注入的解析函数,根据传入的依赖描述符和相关参数来解析依赖,并返回解析后的依赖对象。根据依赖类型的不同,函数采取不同的解析逻辑,包括创建可选的依赖对象、创建依赖对象提供者、创建JSR330依赖提供者等。如果以上条件都不满足,则调用另一个函数进行解析。

其中createOptionalDependency的源码如下:

	/**
	 * 创建一个指定依赖项的 {@link Optional} 外套。
	 */
	private Optional<?> createOptionalDependency(
			DependencyDescriptor descriptor, @Nullable String beanName, final Object... args) {
 
		DependencyDescriptor descriptorToUse = new NestedDependencyDescriptor(descriptor) {
			@Override
			public boolean isRequired() {
				return false;
			}
 
			@Override
			public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) {
				return (!ObjectUtils.isEmpty(args) ? beanFactory.getBean(beanName, args) :
						super.resolveCandidate(beanName, requiredType, beanFactory));
			}
		};
 
		Object result = doResolveDependency(descriptorToUse, beanName, null, null);
		return (result instanceof Optional<?> optional ? optional : Optional.ofNullable(result));
	}

这个函数用于创建一个包含所依赖对象的Optional包装。它接受一个DependencyDescriptor对象表示依赖的描述,可选的beanName和依赖对象的参数。函数会创建一个NestedDependencyDescriptor对象来重写一些方法,然后调用doResolveDependency函数来获取依赖对象。doResolveDependency的源码如下:

/**
 * 解析依赖注入描述器的依赖项,并返回对象。
 *
 * @param descriptor 依赖注入描述器,用于描述依赖项的类型和作用域等信息
 * @param beanName 被自动注入的bean名称
 * @param autowiredBeanNames 自动注入的bean名称集合
 * @param typeConverter 类型转换器,用于将字符串转换为指定类型的对象
 * @return 解析出的依赖项对象
 * @throws BeansException 如果解析依赖项时发生Beans异常,则抛出该异常
 */
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
        @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
 
    InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
    try {
        // Step 1: 针对单个bean匹配的快捷方式,例如@Autowired
        Object shortcut = descriptor.resolveShortcut(this);
        if (shortcut != null) {
            return shortcut;
        }
 
        Class<?> type = descriptor.getDependencyType();
 
        // Step 2: 预定义的值或表达式,例如@Value
        Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
        if (value != null) {
            if (value instanceof String strValue) {
                String resolvedValue = resolveEmbeddedValue(strValue);
                BeanDefinition bd = (beanName != null && containsBean(beanName) ?
                        getMergedBeanDefinition(beanName) : null);
                value = evaluateBeanDefinitionString(resolvedValue, bd);
            }
            TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
            try {
                return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
            }
            catch (UnsupportedOperationException ex) {
                // 无法进行TypeDescriptor解析的自定义TypeConverter
                return (descriptor.getField() != null ?
                        converter.convertIfNecessary(value, type, descriptor.getField()) :
                        converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
            }
        }
 
        // Step 3a: 将多个beans解析为流、数组、标准集合或普通map
        Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
        if (multipleBeans != null) {
            return multipleBeans;
        }
        // Step 3b: 直接匹配的beans,可能是Collection / Map类型beans的直接beans
        Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
        if (matchingBeans.isEmpty()) {
            // Step 3c(fallback):用于收集多个beans的自定义Collection / Map声明
            multipleBeans = resolveMultipleBeansFallback(descriptor, beanName, autowiredBeanNames, typeConverter);
            if (multipleBeans != null) {
                return multipleBeans;
            }
            // 如果找不到必要的注入点,则抛出异常
            if (isRequired(descriptor)) {
                raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
            }
            return null;
        }
 
        String autowiredBeanName;
        Object instanceCandidate;
 
        // Step 4: 确定单个候选者
        if (matchingBeans.size() > 1) {
            autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
            if (autowiredBeanName == null) {
                if (isRequired(descriptor) || !indicatesArrayCollectionOrMap(type)) {
                    // 如果没有明确的匹配项,并且是必要的注入点,则抛出异常
                    return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
                }
                else {
                    // 如果是非必要的Collection / Map,则静默忽略多个普通beans的非唯一情况
                    return null;
                }
            }
            instanceCandidate = matchingBeans.get(autowiredBeanName);
        }
        else {
            // 我们只有一个匹配项
            Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
            autowiredBeanName = entry.getKey();
            instanceCandidate = entry.getValue();
        }
 
        // Step 5: 验证单个结果
        if (autowiredBeanNames != null) {
            autowiredBeanNames.add(autowiredBeanName);
        }
        if (instanceCandidate instanceof Class) {
            instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
        }
        Object result = instanceCandidate;
        if (result instanceof NullBean) {
            if (isRequired(descriptor)) {
                // 如果为必要的注入点,则抛出null异常
                raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
            }
            result = null;
        }
        if (!ClassUtils.isAssignableValue(type, result)) {
            throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
        }
        return result;
    }
    finally {
        ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
    }
}

这个函数是一个依赖注入的方法,用于解析依赖注入请求并返回相应的对象。它接受几个参数,包括依赖描述符、bean名称、自动注入的bean名称集合和类型转换器。它使用不同的步骤来处理不同的情况,包括解析快捷方式、预定义的值或表达式、多个bean的解析、直接匹配的bean和候选bean的解析。最后,它返回解析后的对象。

  /**
   * 解析多个bean对象
   *
   * @param descriptor 依赖描述符
   * @param beanName bean名称
   * @param autowiredBeanNames autowired bean名称集合
   * @param typeConverter 类型转换器
   * @return 解析得到的bean对象
   */
  @Nullable
  private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
          @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
 
      Class<?> type = descriptor.getDependencyType();
 
      if (descriptor instanceof StreamDependencyDescriptor streamDependencyDescriptor) {
          Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
          if (autowiredBeanNames != null) {
              autowiredBeanNames.addAll(matchingBeans.keySet());
          }
          Stream<Object> stream = matchingBeans.keySet().stream()
                  .map(name -> descriptor.resolveCandidate(name, type, this))
                  .filter(bean -> !(bean instanceof NullBean));
          if (streamDependencyDescriptor.isOrdered()) {
              stream = stream.sorted(adaptOrderComparator(matchingBeans));
          }
          return stream;
      }
      else if (type.isArray()) {
          Class<?> componentType = type.componentType();
          ResolvableType resolvableType = descriptor.getResolvableType();
          Class<?> resolvedArrayType = resolvableType.resolve(type);
          if (resolvedArrayType != type) {
              componentType = resolvableType.getComponentType().resolve();
          }
          if (componentType == null) {
              return null;
          }
          Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
                  new MultiElementDescriptor(descriptor));
          if (matchingBeans.isEmpty()) {
              return null;
          }
          if (autowiredBeanNames != null) {
              autowiredBeanNames.addAll(matchingBeans.keySet());
          }
          TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
          Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType);
          if (result instanceof Object[] array && array.length > 1) {
              Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
              if (comparator != null) {
                  Arrays.sort(array, comparator);
              }
          }
          return result;
      }
      else if (Collection.class == type || Set.class == type || List.class == type) {
          return resolveMultipleBeanCollection(descriptor, beanName, autowiredBeanNames, typeConverter);
      }
      else if (Map.class == type) {
          return resolveMultipleBeanMap(descriptor, beanName, autowiredBeanNames, typeConverter);
      }
      return null;
  }

这个函数用于解析多个依赖 bean。它接受几个参数,包括依赖类型、bean 名称、自动注入的 bean 名称集合和类型转换器。根据依赖类型的不同,它使用不同的逻辑来解析匹配的 bean,并返回解析结果。如果解析成功,它会将自动注入的 bean 名称添加到自动注入的 bean 名称集合中。最后,它根据解析结果的类型返回不同的值,包括流、数组、集合、映射等。如果解析失败,它返回空值。

	/**
	 * 解析多个依赖的集合对象
	 * 
	 * @param descriptor 依赖描述器
	 * @param beanName bean名称
	 * @param autowiredBeanNames 自动注入的bean名称集合
	 * @param typeConverter 类型转换器
	 * @return 解析后的对象
	 */
	@Nullable
	private Object resolveMultipleBeanCollection(DependencyDescriptor descriptor, @Nullable String beanName,
			@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
 
	    // 获取可解析的类型
		Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
		if (elementType == null) {
			return null;
		}
		
		// 查找与类型匹配的自动注入候选bean
		Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
				new MultiElementDescriptor(descriptor));
		if (matchingBeans.isEmpty()) {
			return null;
		}
		
		// 添加匹配的bean名称到自动注入的bean名称集合
		if (autowiredBeanNames != null) {
			autowiredBeanNames.addAll(matchingBeans.keySet());
		}
		
		// 获取类型转换器
		TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
		
		// 根据依赖类型将结果进行类型转换
		Object result = converter.convertIfNecessary(matchingBeans.values(), descriptor.getDependencyType());
		
		// 如果结果是列表且大小大于1,则根据依赖比较器对列表进行排序
		if (result instanceof List<?> list && list.size() > 1) {
			Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
			if (comparator != null) {
				list.sort(comparator);
			}
		}
		
		return result;
	}

这个函数用于解析多个依赖项的集合。它接受一个依赖描述符、一个可选的bean名称、一个可选的自动注入bean名称集合、一个可选的类型转换器作为参数。它首先解析依赖项类型为集合,并检查元素类型是否为空,如果为空则返回null。然后找到与给定bean名称和元素类型匹配的自动注入bean,并将其添加到匹配bean名称集合中。如果给定的自动注入bean名称集合不为空,则将匹配的bean名称添加到该集合中。然后根据依赖项类型进行类型转换,并返回转换后的结果。如果结果是一个元素类型为List的集合且集合大小大于1,则根据适应的依赖项比较器对集合进行排序。最后返回结果。

/**
 * 解析多个bean的map结构的依赖项。
 *
 * @param descriptor 依赖项描述器
 * @param beanName bean名称
 * @param autowiredBeanNames 自动注入的bean名称集合
 * @param typeConverter 类型转换器
 * @return 转换后的依赖项对象
 */
@Nullable
private Object resolveMultipleBeanMap(DependencyDescriptor descriptor, @Nullable String beanName,
                                      @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
 
    // 获取map类型
    ResolvableType mapType = descriptor.getResolvableType().asMap();
    // 获取key类型
    Class<?> keyType = mapType.resolveGeneric(0);
    // 如果key类型不是String,则返回null
    if (String.class != keyType) {
        return null;
    }
    // 获取value类型
    Class<?> valueType = mapType.resolveGeneric(1);
    // 如果value类型为空,则返回null
    if (valueType == null) {
        return null;
    }
    // 查找与给定value类型匹配的自动注入bean
    Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
            new MultiElementDescriptor(descriptor));
    // 如果没有匹配的bean,则返回null
    if (matchingBeans.isEmpty()) {
        return null;
    }
    // 如果autowiredBeanNames不为空,则将匹配的bean的键添加到autowiredBeanNames中
    if (autowiredBeanNames != null) {
        autowiredBeanNames.addAll(matchingBeans.keySet());
    }
    // 获取类型转换器
    TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
    // 将匹配的bean转换为依赖项类型并返回
    return converter.convertIfNecessary(matchingBeans, descriptor.getDependencyType());
}

这个函数用于解析依赖注入描述符,根据描述符的要求寻找匹配的bean,并将其转换为指定的类型返回。如果找不到匹配的bean或者bean的类型转换失败,则返回null。同时,如果autowiredBeanNames不为空,则将其添加匹配的bean的键集合。最后,根据要求的类型进行类型转换并返回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值