0
点赞
收藏
分享

微信扫一扫

spring核心源码分析第二十篇 refresh流程之populateBean

云卷云舒xj 2022-01-05 阅读 28

文章目录

populateBean一流程图

  • 存在InstantiationAwareBeanPostProcessor自定义依赖注入,则调用postProcessAfterInstantiation;根据postProcessAfterInstantiation返回Boolean值决定是否完成spring自带DI
  • 如果配置了autowired_by_name,则根据名称进行注入
  • 如果配置了autowired_by_type,则根据类型进行注入
  • 通过InstantiationAwareBeanPostProcessor处理注解注入
  • 处理xml等方式配置的properties注入

在这里插入图片描述

populateBean-源码分析

  • 1 InstantiationAwareBeanPostProcessor注入
  • 2 spring 自动注入autowired By Name or Type
  • 3 注解注入
  • 4 xml注入
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
	......删除其他代码
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				 *  如果返回false则终止DI注入
				 *  -----------------------
				 *  如果你定义一个InstantiationAwareBeanPostProcessor
				 *  在postProcessAfterInstantiation里完成了DI 并返回false 则完成自定义的DI过程 或者直接返回false
				 *  说明你期望终止特定bean的注入过程
				 *  而如果返回true说明你期望自定义DI与springDI共同作用
				 *  -----------------------
				step-1: postProcessAfterInstantiation表示实例化之后 Initialization表示初始化之后 实例化之后未加入bean容器管理 初始化之后已经加入singletonObjects被bean容器管理
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}
	}
	取容器在解析bean定义资源时为bd设置的PropertyValues,一般我们在xml中配置
	PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
	int resolvedAutowireMode = mbd.getResolvedAutowireMode();
	step-2:判断是根据名称注入还是类型注入 =如果是默认则跳过这里 一般情况下我们采用AUTOWIRE_NO[spring不自动注入而是通过注解注入]
	注入方式 分为 AUTOWIRE_BY_NAME AUTOWIRE_BY_TYPE AUTOWIRE_NO等[也就是采用名称注入 type注入 还是no依赖注解或者xml配置注入]
	if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
			autowireByName(beanName, mbd, bw, newPvs);
		}
		if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			autowireByType(beanName, mbd, bw, newPvs);
		}
		pvs = newPvs;
	}
	...... 删除其他代码
	if (hasInstAwareBpps || needsDepCheck) {
		step-3: 获取所有getter/setter对应的属性值 不仅仅是@autowired等spring注解的属性而是这个bean的所有属性值比如通用的getClass对应的class属性值
		PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		if (hasInstAwareBpps) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				 * AutowiredAnnotationBeanPostProcessor 處理@Autowired @Value @Inject* CommonAnnotationBeanPostProcessor 負責@Resource |  @PostConstruct @PreDestroy(交給父类处理)*
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvs == null) {
						return;
					}
				}
			}
		}
		...... 删除依赖检查
	}

	if (pvs != null) {
			step-4: 属性DI注入 PropertyValues是一般值xml配置的properties 
		采用set注入
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
	结合这个流程可以看出 存在多个对相同的属性的注入 比如同时配置注解与xml 最终生效流程如下
	自定义注入--> AUTOWIRE_BY_NAME-->AUTOWIRE_BY_TYPE->注解注入[CommonAnnotationBeanPostProcessor -> AutowiredAnnotationBeanPostProcessor]--> xml注入
}

总结

  • 依赖注入中存在一个核心问题,单例bean的循环依赖[参见二十一篇]
  • postProcessProperties和postProcessPropertyValues的功能一致,区别在于前者依赖Metadata ,后者依赖PropertyDescriptor,后者未来版本应该会被淘汰
  • 注解注入的两个核心BPP如下
CommonAnnotationBeanPostProcessorAutowiredAnnotationBeanPostProcessor
处理@Resource @PostConstruct @PreDestroy 等@Autowired @Value @Inject等
  • 注入方式有构造注入 名称注入 类型注入 注解注入以及自定义等多种方式
autowired_by_nameautowired_by_typeautowire_constructorautowire_no注解注入
  • 如果存在一个属性值多次注入,最后执行DI的覆盖前置,顺序如下
举报

相关推荐

0 条评论