【Spring源码阅读】populateBean实现 依赖注入源码解析

版权声明:转载请注明本文源地址 https://blog.csdn.net/qwe6112071/article/details/85225507

在完成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容器的依赖注入实现基础流程。

猜你喜欢

转载自blog.csdn.net/qwe6112071/article/details/85225507