9、Spring之Bean生命周期~依赖注入(总)

9、Spring之Bean生命周期~依赖注入(总)

依赖注入

spring有几种依赖注入方式

  从类型角度区分,分两种:手动和自动

手动注入:通过XML中定义Bean时,可手动注入

<!-- 通过set方法注入 -->
<bean name="userService" class="com.luban.service.UserService">
	<property name="orderService" ref="orderService"/>
</bean>

<!-- 通过构造器注入 -->
<bean name="userService" class="com.luban.service.UserService">
	<constructor-arg index="0" ref="orderService"/>
</bean>

自动注入

// xml的形式配置自动注入
<bean id="userService" class="com.luban.service.UserService" autowire="byType"/>

// @Autowired 注解自动注入
@Autowired	

// @Value 注解自动注入 
@Value

// @Inject 注解自动注入 
@Inject

// @Resource 注解自动注入 
@Resource

// @Bean 注解中的autowire属性自动注入 (已废弃)
@Bean(autowire = Autowire.BY_NAME)
@Bean(autowire = Autowire.BY_type)

源码解析

  Bean实例化后和初始化之间会进行属性填充,接下来我们将解析属性填充的具体步骤,废话不多说,上代码:

/**
 * Populate the bean instance in the given BeanWrapper with the property values
 * from the bean definition.
 *
 * @param beanName the name of the bean
 * @param mbd      the bean definition for the bean
 * @param bw       the BeanWrapper with bean instance
 */
@SuppressWarnings("deprecation")  // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
	if (bw == null) {
		if (mbd.hasPropertyValues()) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
		} else {
			// Skip property population phase for null instance.
			return;
		}
	}

	// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
	// state of the bean before properties are set. This can be used, for example,
	// to support styles of field injection.
	// 实例化之后,属性设置之前
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
			// 执行 InstantiationAwareBeanPostProcessors接口的postProcessAfterInstantiation()方法 根据返回值判断是否跳过属性填充
			if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
				return;
			}
		}
	}

	/**
	 *
	 * 处理spring自带的依赖注入的功能 @Bean(autowire = Autowire.BY_NAME)
	 *
	 * */
	PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
	int resolvedAutowireMode = mbd.getResolvedAutowireMode();
	if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
		// MutablePropertyValues是PropertyValues具体的实现类
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
		// Add property values based on autowire by name if applicable.
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
			autowireByName(beanName, mbd, bw, newPvs);
		}
		// Add property values based on autowire by type if applicable.
		if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			autowireByType(beanName, mbd, bw, newPvs);
		}
		pvs = newPvs;
	}

	boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
	boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

	PropertyDescriptor[] filteredPds = null;
	if (hasInstAwareBpps) {
		if (pvs == null) {
			pvs = mbd.getPropertyValues();
		}
		for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
			// 这里会调用AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法,会直接给对象中的属性赋值
			// AutowiredAnnotationBeanPostProcessor内部并不会处理pvs,直接返回了
			PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
			if (pvsToUse == null) {
				if (filteredPds == null) {
					filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
				}
				pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					return;
				}
			}
			pvs = pvsToUse;
		}
	}
	if (needsDepCheck) {
		if (filteredPds == null) {
			filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		}
		checkDependencies(beanName, mbd, filteredPds, pvs);
	}

	// 如果当前Bean中的BeanDefinition中设置了PropertyValues,那么最终将是PropertyValues中的值,覆盖@Autowired
	if (pvs != null) {
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
}

  通过上述代码我们可以看到:

  1. 首先,第一个判断是检验Bean对象不是null;
  2. 第二个判断,当一个BeanPostProcessor实现啦InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation()方法,并且返回flash时,就不会走属性填充,返回true时,会继续走属性填充;Spring在这一步通过AutowiredAnnotationBeanPostProcessor类的中postProcessMergedBeanDefinition方法寻找@Value和@Autoword的注入点,CommonAnnotationBeanPostProcessor类中的postProcessMergedBeanDefinition方法寻找@Resource的注入点;
  3. 再往下,处理@Bean(autowire = Autowire.BY_NAME)和@Bean(autowire = Autowire.BY_NAME),详情请移步至《Spring之Bean生命周期~依赖注入(1)》;
  4. 再往下,会循环所有实现InstantiationAwareBeanPostProcessor接口的BeanPostProcessor,调用它的postProcessProperties()方法,Spring在这一步通过AutowiredAnnotationBeanPostProcessor类的中postProcessProperties方法给@Value和@Autoword进行注入操作,CommonAnnotationBeanPostProcessor类中的postProcessProperties方法给@Resource的进行注入操作;AutowiredAnnotationBeanPostProcessor类相关依赖注入源码请移步至《Spring之Bean生命周期~依赖注入(2)》,CommonAnnotationBeanPostProcessor类相关依赖注入源码请移步至《Spring之Bean生命周期~依赖注入(3)
  5. 最后,如果当前Bean中的BeanDefinition中设置了PropertyValues,那么最终将是PropertyValues中的值,覆盖@Autowired、@Value、@Resource;

相关推荐

  1. 9SpringBean生命周期~依赖注入

    2024-06-16 18:40:04       6 阅读
  2. 11、SpringBean生命周期~依赖注入(2)

    2024-06-16 18:40:04       8 阅读
  3. 2、SpringBean生命周期~扫描

    2024-06-16 18:40:04       6 阅读
  4. 7、SpringBean生命周期~初始化

    2024-06-16 18:40:04       8 阅读
  5. 8、SpringBean生命周期~销毁

    2024-06-16 18:40:04       4 阅读
  6. 4、SpringBean生命周期~获取Bean

    2024-06-16 18:40:04       9 阅读
  7. 5、SpringBean生命周期~创建Bean(1)

    2024-06-16 18:40:04       7 阅读
  8. 6、SpringBean生命周期~创建Bean(2)

    2024-06-16 18:40:04       7 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-16 18:40:04       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-16 18:40:04       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-16 18:40:04       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-16 18:40:04       18 阅读

热门阅读

  1. Linux 使用chown修改文件所属用户 用户组

    2024-06-16 18:40:04       10 阅读
  2. 网络熔断机制(Circuit Breaker)

    2024-06-16 18:40:04       8 阅读
  3. 使用python获取内存信息

    2024-06-16 18:40:04       11 阅读
  4. 分布式事务之TCC

    2024-06-16 18:40:04       6 阅读
  5. 抉择与未来:计算机专业的选择与发展展望

    2024-06-16 18:40:04       7 阅读
  6. 数据仓库和数据库的区别

    2024-06-16 18:40:04       7 阅读
  7. 中介子方程十九

    2024-06-16 18:40:04       8 阅读