一、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 异常。
实例策略