标题:Spring源码解析之推断构造方法
前言
在Spring的IoC容器中,我们可以使用自动装配的方式注入Bean实例,Spring会根据构造方法参数的类型和名称来自动匹配注入对应类型的实例。Spring是如何实现自动装配的呢?从源码层面解析,自动装配的核心就是推断构造方法。
推断构造方法
Spring会尝试推断某个Bean的构造方法,根据该构造方法参数类型和名称匹配注入对应类型的实例。推断构造方法的策略分为三个步骤:
- 查找构造方法列表,获取所有public访问修饰符的构造器;
- 选取合适的构造方法;
- 利用选中的构造方法进行实例化。
查找构造方法列表
在获取构造方法列表时,Spring会使用Class.getConstructors()方法获取当前类的所有构造器,并将其封装在Constructor数组中返回。示例代码如下:
//获取构造方法列表
Constructor<?>[] constructors = beanClass.getConstructors();
选取合适的构造方法
在获取构造方法列表之后,Spring会尝试选取合适的构造方法。选取构造方法的策略如下:
- 构造方法的参数个数最少的优先选取;
- 构造方法中参数类型与其他Bean的类型有直接依赖关系的优先选取;
- 若以上两点都无法确定,则选择第一个构造方法。
需要注意的是,只有在Bean的定义中没有明确指定构造方法的方式时,Spring才会尝试推断构造方法。示例代码如下:
//选取合适的构造方法
Constructor<?> constructorToUse = beanDefinition.constructorToUse;
if (constructorToUse == null) {
for (Constructor<?> constructor : constructors) {
...
}
}
利用构造方法进行实例化
在选取合适的构造方法之后,Spring会使用该构造方法创建一个新的Bean实例。示例代码如下:
//实例化Bean
Object[] argsToUse = determineConstructArguments(beanName, beanDefinition, selectedValues);
beanInstance = BeanUtils.instantiateClass(constructorToUse, argsToUse);
示例说明
示例1
有一个DemoController类,声明了两个依赖,分别是DemoService和DemoRepository:
@Controller
public class DemoController {
private final DemoService demoService;
private final DemoRepository demoRepository;
public DemoController(DemoService demoService, DemoRepository demoRepository) {
this.demoService = demoService;
this.demoRepository = demoRepository;
}
...
}
在使用自动装配的方式将DemoService和DemoRepository注入DemoController时,Spring会自动推断构造方法,并选取构造方法来实例化Bean对象,示例代码如下:
<bean id="demoService" class="com.example.DemoService" />
<bean id="demoRepository" class="com.example.DemoRepository" />
<bean id="demoController" class="com.example.DemoController" autowire="constructor" />
示例2
有一个DemoService类,声明了一个依赖,注入了一个DemoDao:
@Service
public class DemoService {
private final DemoDao demoDao;
public DemoService(DemoDao demoDao) {
this.demoDao = demoDao;
}
...
}
在使用自动装配的方式将DemoDao注入DemoService时,Spring会自动推断构造方法,并选取构造方法来实例化Bean对象,示例代码如下:
<bean id="demoDao" class="com.example.DemoDao" />
<bean id="demoService" class="com.example.DemoService" autowire="constructor" />
结语
本文从源码层面分析了Spring自动装配的核心——推断构造方法的实现策略,希望对理解Spring源码和使用Spring框架有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring源码解析之推断构造方法 - Python技术站