【Spring-5.2】AbstractAutowireCapableBeanFactory#populateBean实现Bean的属性赋值

本文深入分析了Spring中Bean属性注入的过程,重点讲解了AbstractAutowireCapableBeanFactory#populateBean方法如何实现属性赋值。讨论了@Autowired和@Resource注解的处理,包括静态属性和方法的注入问题,以及依赖解析的细节,如泛型匹配和选择合适候选者的策略。
摘要由CSDN通过智能技术生成

本章是属性注入的详细分析

默认情况下,spring不会主动给bean注入是属性的,开发者需要自己配置,首先明确的是对象有哪些属性需要注入,注入的类型是按照类型还是按照名称。之前这些可以在xml文件中配置,但是在开发中最好是通过注解的方式实现,所以用到了@autowired,@resource注解,需要注入的属性,使用注解标注即可。spring是怎么知道对象中哪些属性用注解标注了呢?

进入方法AbstractAutowireCapableBeanFactory#doCreateBean,在创建完实例之后,有一步调用处理器的postProcessMergedBeanDefinition方法,属性注入之前对bd的最后操作。

		synchronized (mbd.postProcessingLock) {
   
			if (!mbd.postProcessed) {
   
				try {
   
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
   
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

bean处理器中有两个是用来处理@autowired,@resource注解的
AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
两个处理器的逻辑大致相似,本文以AutowiredAnnotationBeanPostProcessor处理器为例进行分析,下面进入到AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition方法

	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
   
		// InjectionMetadata 保存了这个bean的需要注入的属性
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}

构建保存实例属性的对象InjectionMetadata。

	private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
   
		// 
		String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
		// 从缓存中取数据
		InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
		// 如果数据是null 或者数据中保存的对象和clazz对不上了,就需要刷新,进入方法
		if (InjectionMetadata.needsRefresh(metadata, clazz)) {
   
			synchronized (this.injectionMetadataCache) {
   
				metadata = this.injectionMetadataCache.get(cacheKey);
				if (InjectionMetadata.needsRefresh(metadata, clazz)) {
   
					// 如果之前有数据,则清空
					if (metadata != null) {
   
						metadata.clear(pvs);
					}
					//重新构建注入的属性
					metadata = buildAutowiringMetadata(clazz);
					// 放入换粗
					this.injectionMetadataCache.put(cacheKey, metadata);
				}
			}
		}
		return metadata;
	}

从缓存中取数据,如果没有就直接构建对象。

	private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
   
		// 是否这个类的属性有用注解标注的属性(@autowired @value),如果没有直接返回空了
		if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
   
			return InjectionMetadata.EMPTY;
		}

		List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
		Class<?> targetClass = clazz;

		do {
   
			final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
			// 利用反射得到这个类的属性,根据属性得到属性上的注解
			ReflectionUtils.doWithLocalFields(targetClass, field -> {
   
				MergedAnnotation<?> ann = findAutowiredAnnotation(field);
				if (ann != null) {
   
					if (Modifier.isStatic(field.getModifiers())) {
   
						if (logger.isInfoEnabled()) {
   
							logger.info("Autowired annotation is not supported on static fields: " + field);
						}
						return;
					}
					boolean required = determineRequiredStatus(ann);
					// 创建对象放入集合
					currElements.add(new AutowiredFieldElement(field, required));
				}
			});
			// 方法也是同样的逻辑
			ReflectionUtils.doWithLocalMethods(targetClass, method -> {
   
				Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
				if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
   
					return;
				}
				MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
				if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
   
					if (Modifier.isStatic(method.getModifiers())) {
   
						if (logger.isInfoEnabled()) {
   
							logger.info("Autowired annotation is not supported on static methods: " + method);
						}
						return;
					}
					if (method.getParameterCount() == 0) {
   
						if (logger.isInfoEnabled()) {
   
							logger.info("Autowired annotation should only be used on methods with parameters: " +
									method);
						}
					}
					boolean required = determineRequiredStatus(ann);
					PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
					currElements.add(new AutowiredMethodElement(method, required, pd));
				}
			});

			elements.addAll(0, currElements);
			targetClass = targetClass.getSuperclass();
		}
		while (targetClass != null && targetClass != Object.class);
		// 创建InjectionMetadata对象
		return InjectionMetadata.forElements(elements, clazz);
	}

根据反射得到类的属性,如果属性有@autowired注解,就先将该属性信息创建AutowiredFieldElement对象,得到所有的属性集合,创建InjectionMetadata信息。可以看到InjectionMetadata保存了目标bean的class信息和需要注入的属性集合。注意,关于属性和方法,静态的都不能注入。

下面开始进入属性注入AbstractAutowireCapableBeanFactory#populateBean

	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;
			}
		}

		// 实例化之后的操作,如果返回的是false,就不在注入了。
		// 实例化处理器的实例化之后的处理器方法
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
   
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
   
				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
   
					return;
				}
			}
		}
		
		//先看bd中是否已经设置了需要注入的属性。通常有值的都是xml配置的,或者是自定义的bd.
		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
		
		// 默认是不注入的AUTOWIRE_NO
		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
   
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// 通过名称找到 key: propertyName, value:bean
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
   
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// 通过类型找
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
   
				autowireByType(beanName, mbd, bw, newPvs);
			}
			// 无论是按照名称注入还是按照类型注入,会把实例和属性名称保存在newPvs中,现在还没有注入属性呢
			pvs = newPvs;
		}
		// 上面的逻辑过后,newPvs中的集合中对象类似一个k-v对,key是属性,value是注入的对象。

		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) {
   
				// 这里的是处理属性的处理器,其实就是保存@autowired和@resource注解的处理器。这里有注入逻辑,通过field,得到相应的bean,最后通过反射给属性赋值。
				PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
   
					if (filteredPds == null) {
   
						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值