spring源码深入分析applyMergedBeanDefinitionPostProcessors接口

spring源码深入分析applyMergedBeanDefinitionPostProcessors接口,这是一个非常重要的接口,其功能是:

有CommonAnnotationBeanPostProcessor  支持了@PostConstruct,@PreDestroy,@Resource注解;
有AutowiredAnnotationBeanPostProcessor 支持 @Autowired,@Value注解;
有BeanPostProcessor接口的典型运用,这里要理解这个接口,对类中注解的装配过程。

1、源码入口:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//创建实例,在内存中开辟空间,但是对象里面的参数还没有赋值
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					//CommonAnnotationBeanPostProcessor  支持了@PostConstruct,@PreDestroy,@Resource注解
					//AutowiredAnnotationBeanPostProcessor 支持 @Autowired,@Value注解
					//BeanPostProcessor接口的典型运用,这里要理解这个接口
					//对类中注解的装配过程,收集装配。
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}
 //省略部分代码。。。。。。
}

2、点击进入:applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof MergedBeanDefinitionPostProcessor) {
				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
               //CommonAnnotationBeanPostProcessor  支持了@PostConstruct,@PreDestroy,@Resource注解;AutowiredAnnotationBeanPostProcessor 支持 @Autowired,@Value注解。主要对这两个类的处理
				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
			}
		}
	}

点击显示:

 这里用此类演示:

 3、 点击 bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);进入 AutowiredAnnotationBeanPostProcessor 类

	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        //点击进入
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}

4、点击findAutowiringMetadata 方法:



	private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
		// Fall back to class name as cache key, for backwards compatibility with custom callers.
		String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
		// Quick check on the concurrent map first, with minimal locking.
        // cache里面包装有注解的属性和方法
		InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
		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;
	}

点击buildAutowiringMetadata 方法:


	private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
		if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
			return InjectionMetadata.EMPTY;
		}
        //定义一个大的最外层的包装类,包装整个类的有@Autowir注解的对象
		List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
		Class<?> targetClass = clazz;

		do {//定义包装类,包装参数和方法有@Autowir的注解的对象
			final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

			//寻找属性参数field上面的@Autowired注解并封装成对象
			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);
                    //找到有@Autowired注解的属性和注解的值封装成一个对象
					currElements.add(new AutowiredFieldElement(field, required));
				}
			});

			//寻找Method上面的@Autowired注解并封装成对象
			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);

		return InjectionMetadata.forElements(elements, clazz);
	}

此处发现此内部类的子类:

 后面的两行代码可以证明:


currElements.add(new AutowiredFieldElement(field, required));

currElements.add(new AutowiredMethodElement(method, required, pd));

 

 参数演示:

进入 findAutowiredAnnotation 方法:

@Nullable
	private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
		MergedAnnotations annotations = MergedAnnotations.from(ao);
		for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
            //取出此参数的注解
			MergedAnnotation<?> annotation = annotations.get(type);
			if (annotation.isPresent()) {
				return annotation;
			}
		}
		return null;
	}

 如图:如果符合一个就直接返回

 此处就找这两个中的一个:

 返回后此处建立映射关系:

 这里封装成InjectionMetadata对象返回:

 返回后又建立一个对应关系:

 5、返后调用  metadata.checkConfigMembers(beanDefinition); 方发,进入InjectionMetadata类


	public void checkConfigMembers(RootBeanDefinition beanDefinition) {
		Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
		for (InjectedElement element : this.injectedElements) {
			Member member = element.getMember();
			if (!beanDefinition.isExternallyManagedConfigMember(member)) {
				beanDefinition.registerExternallyManagedConfigMember(member);
				checkedElements.add(element);
				if (logger.isTraceEnabled()) {
					logger.trace("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
				}
			}
		}
		this.checkedElements = checkedElements;
	}

对应赋值操作:

最终有返回到遍历的这里:

 到此,关于类上的参数和方法上有 @Autowired注解的收集和保存分享完毕,大家一定要详细阅读,多多思考定会早日掌握。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寅灯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值