在完成Bean实例化后,Spring容器会给这个Bean注入相关的依赖Bean,在源码中,这一步通过类AbstractAutowireCapableBeanFactory中的populateBean
方法完成。
测试代码
下面开始进入源码分析之前,先基于以下实例进行:
// 基础属性类
public class Student {
private String name;
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [name=" + name + "]";
}
}
// 需要进行依赖注入的类
public class TestBean {
private Student student;
public void echo() {
System.out.println("I'm a student : " + student);
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
}
配置代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean class="com.jeanheo.model.Student" id="student">
<constructor-arg index="0" value="test"/>
</bean>
<bean class="com.jeanheo.model.TestBean2" id="testBean">
<property name="student" ref="student"/>
</bean>
</beans>
具体测试代码:
public class BaseTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
TestBean testBean = context.getBean("testBean", TestBean.class);
testBean.echo();
}
}
源码分析
下面基于TestBean的依赖注入进行分析相关源码:
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// pvs是一个MutablePropertyValues实例,里面实现了PropertyValues接口,提供属性的读写操作实现,同时可以通过调用构造函数实现深拷贝
// 在本例中,里面存在一个propertyValueList,里面只有一个propertyValue:key->value="student"->RuntimeBeanReference("<student>")
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// 空对象直接返回
return;
}
}
// 给InstantiationAwareBeanPostProcessors最后一次机会在属性注入前修改Bean的属性值
// 具体通过调用postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
// 根据Bean配置的依赖注入方式完成注入,默认是0,即不走以下逻辑,所有的依赖注入都需要在xml文件中有显式的配置
// 如果设置了相关的依赖装配方式,会遍历Bean中的属性,根据类型或名称来完成相应注入,无需额外配置
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
// 深拷贝当前已有的配置
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 根据名称进行注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// // 根据类型进行注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
// 结合注入后的配置,覆盖当前配置
pvs = newPvs;
}
// 容器是否注册了InstantiationAwareBeanPostProcessor
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 是否进行依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
// 过滤出所有需要进行依赖检查的属性编辑器
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// 如果有相关的后置处理器,进行后置处理
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
// 检查是否满足相关依赖关系,对应的depends-on属性,需要确保所有依赖的Bean先完成初始化
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
// 将pvs上所有的属性填充到BeanWrapper对应的Bean实例中,注意到这一步,TestBean的student属性还是RuntimeBeanReference,即还未解析实际的Student实例
applyPropertyValues(beanName, mbd, bw, pvs);
}
在具体分析源码如何将将pvs上所有的属性填充到BeanWrapper对应的Bean实例中之前,先看看autowireByName和autowireByType这两步是怎么实现的:
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 根据bw的PropertyDescriptors,遍历出所有可写的(即set方法存在),存在于BeanDefinition里的PropertyValues,且不是简单属性的属性名
// 简单属性的判定参照下面方法,主要涵盖基本类型及其包装类,Number,Date等
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
// 递归初始化相关Bean
Object bean = getBean(propertyName);
// 根据名称添加到pvs中
pvs.add(propertyName, bean);
// 注册依赖关系
registerDependentBean(propertyName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
// 简单类型判定
public static boolean isSimpleValueType(Class<?> clazz) {
return ClassUtils.isPrimitiveOrWrapper(clazz) || clazz.isEnum() ||
CharSequence.class.isAssignableFrom(clazz) ||
Number.class.isAssignableFrom(clazz) ||
Date.class.isAssignableFrom(clazz) ||
clazz.equals(URI.class) || clazz.equals(URL.class) ||
clazz.equals(Locale.class) || clazz.equals(Class.class);
}
类似的,下面再看看autowireByType的实现
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 获取类型转换器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
// 类似的,过滤出满足装配条件的Bean属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
如果是Object类型不进行装配
if (!Object.class.equals(pd.getPropertyType())) {
// 获取相关的写方法参数
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// 定义是否允许懒加载。
boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
//
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
// 这里会根据传入desc里的入参类型,作为依赖装配的类型
// 再根据这个类型在BeanFacoty中查找所有类或其父类相同的BeanName
// 最后根据BeanName获取或初始化相应的类,然后将所有满足条件的BeanName填充到autowiredBeanNames中。
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
// 注册依赖
registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
具体pvs上所有的属性填充到BeanWrapper对应的Bean实例中实现如下:
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
// 为空直接返回
if (pvs == null || pvs.isEmpty()) {
return;
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (System.getSecurityManager() != null) {
if (bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
}
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
// 如果已被设置转换完成,直接完成配置
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
// 创建BeanDefinitionValueResolver解析器,用来解析未被解析的PropertyValue。
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// 开始遍历检查original中的属性,对未被解析的先解析/已解析的直接加入deepCopy中,最后再填充到具体的Bean实例中
List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
// 如果属性已经转化,直接添加
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
// 核心逻辑,解析获取实际的值
// 对于RuntimeReference,会解析拿到具体的beanName,最终通过getBean(beanName)拿到具体的对象
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
// 判断是否可以转换
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
// 尝试进行转换
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// 避免需要重复转换,设定已转换
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// 完成设置
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
上面大致的描述了Spring完成依赖注入的流程,中间具体还有很多细致的复杂处理细节,但通过上述的源码解读,我们大致了解了整个Spring容器的依赖注入实现基础流程。