spring推断构造方法

我们知道spring bean在创建的过程中,通过BeanDefinition的来实例化对象,而实例化对象肯定需要构造方法,大多数情况都是使用默认的无参构造方法。但是spring底层实现考虑的情况非常复杂

主要分为两种情况:一是没有@Autowired修饰的构造方法,二是加了@Autowired修饰的构造方法;

源码思路:

1、创建bean时会调用AbstractAutowireCapableBeanFactory#createBeanInstance()方法

2、根据BeanDefinition加载得到class类 

3、spring在实例化前会先判断程序员在BeanDefinition中是否实现了Supplier,如果实现直接调用Supplier#get()方法返回

4、determineConstructorsFromBeanPostProcessors()查找筛选构造方法,可能返回空或者多个

5、4如果返回多个(包括一个)执行autowireConstructor()方法去推断一个构造方法进行实例化

6、4返回空直接调用instantiateBean()方法,使用无参构造方法实例化一个bean

Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
		mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
	return autowireConstructor(beanName, mbd, ctors, args);
}

// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
	return autowireConstructor(beanName, mbd, ctors, null);
}

// No special handling: simply use no-arg constructor.
// ctors==null,则直接使用无参构造方法
return instantiateBean(beanName, mbd);

spring通过determineConstructorsFromBeanPostProcessors()方法查找并筛选构造方法。

首先看没有@Autowired修饰的情况,如果只有一个无参构造方法或者有多个构造方法,该方法会返回null,最后执行instantiateBean()方法,使用无参构造方法实例化对象;如果该方法返回一个构造方法,执行autowireConstructor()方法(此方法非常复杂,暂不做分析),返回一个实例化对象。

其次,加了@Autowired修饰的情况,如果只有一个required=true的构造方法直接返回此构造方法去执行autowireConstructor()方法;如果有多个required=true的情况或者一个required=true其他的required=false的情况,直接抛异常;如果有多个required=false的情况,就对所有构造方法进行排序,参数个数多的排在前面,参数个数一样,通过参数匹配程度来进行权重计算,分值低的优先使用。参数类型匹配程度越高,分值越低。

@Bean注解的情况

// 处理@Bean注解bean
if (mbd.getFactoryMethodName() != null) {
	return instantiateUsingFactoryMethod(beanName, mbd, args);
}

首先spring在解析@Bean注解的方法时,会将其解析为BeanDefinition,其中BeanDefinition中有一个属性为factoryMethodName,它存储的就是方法名称,用来标识是否@Bean修饰的BeanDefinition。instantiateUsingFactoryMethod()方法逻辑与正常上述的构造方法推断类似,不再赘述。

仅个人笔记

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值