Spring扩展点系列-MergedBeanDefinitionPostProcessor

简介

spring容器中Bean的生命周期内所有可扩展的点的调用顺序
扩展接口 实现接口
ApplicationContextlnitializer initialize
AbstractApplicationContext refreshe
BeanDefinitionRegistryPostProcessor postProcessBeanDefinitionRegistry
BeanDefinitionRegistryPostProcessor postProcessBeanFactory
BeanFactoryPostProcessor postProcessBeanFactory
instantiationAwareBeanPostProcessor postProcessBeforelnstantiation
SmartlnstantiationAwareBeanPostProcessor determineCandidateConstructors
MergedBeanDefinitionPostProcessor postProcessMergedBeanDefinition
InstantiationAwareBeanPostProcessor postProcessAfterlnstantiation
SmartInstantiationAwareBeanPostProcessor getEarlyBeanReference
BeanNameAware setBeanName
BeanFactoryAware postProcessPropertyValues
ApplicationContextAwareProcessor invokeAwarelnterfaces
InstantiationAwareBeanPostProcessor postProcessBeforelnstantiation
@PostConstruct
InitializingBean afterPropertiesSet
FactoryBean getobject
SmartlnitializingSingleton afterSingletonslnstantiated
CommandLineRunner run
DisposableBeandestroy

MergedBeanDefinitionPostProcessor扩展点的作用是对合并后的BeanDefintion进行后置处理。准确的调用时机应该是在创建完 bean 实例之后,接下来会对该接口源码和举例进行说明该扩展点的使用

源码分析

该接口的顶级接口是BeanPostProcessor

public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {

	/**
	 * Post-process the given merged bean definition for the specified bean.
	 * @param beanDefinition 处理后bean definition
	 * @param beanType       解析出来的 bean 的 class
	 * @param beanName       bean 的名字
	 * @see AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
	 */
	void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

	/**
	 * A notification that the bean definition for the specified name has been reset,
	 * and that this post-processor should clear any metadata for the affected bean.
	 * <p>The default implementation is empty.
	 * @param beanName bean 的名字
	 * @since 5.1
	 * @see DefaultListableBeanFactory#resetBeanDefinition
	 */
	default void resetBeanDefinition(String beanName) {
	}

}

找到 applyMergedBeanDefinitionPostProcessors可以看出, MergedBeanDefinitionPostProcessor 的调用是在创建完 bean 实例之后调用。applyMergedBeanDefinitionPostProcessors 方法会获取所有的 MergedBeanDefinitionPostProcessor,并回调它们的 postProcessMergedBeanDefinition 方法
回调 postProcessMergedBeanDefinition 方法时,已经拿到了 merged bean definition,并且还未开始 poplateBean 填充 bean 属性、initlializeBean 初始化 bean 对象,因此可以在这里对 merged bean definition 进行一些操作,在 poplateBean 或 initlializeBean 阶段使用前面操作结果实现所需功能

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 {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			}
			catch (Throwable ex) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Post-processing of merged bean definition failed", ex);
			}
			mbd.postProcessed = true;
		}
	}
	//.....源码省略
}

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
	for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
		processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
	}
}

示例

示例一:Spring中Autowire注解的依赖注入

在Spring 中,AutowiredAnnotationBeanPostProcessor是MergedBeanDefinitionPostProcessor 的一个实现类,该类通过 MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition 方法回调获取 bean 上的 Autowire 注解,并将相关信息保存到缓存中。整体的主要作用是完成 Autowire 注解的依赖注入
在这里插入图片描述

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
	InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
	//checkConfigMembers方法就是遍历从findAutowiringMetadata方法拿到的数据,返回封装这些数据,最后放入到RootBeanDefinition中,也就是bean定义信息中
	metadata.checkConfigMembers(beanDefinition);
}

private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
	// InjectionMetadata会被缓存起来--key为beanName
	String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
	//双重锁机制,确保单例
	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);
				}
				//为当前bean构建InjectionMetadata
				metadata = buildAutowiringMetadata(clazz);
				this.injectionMetadataCache.put(cacheKey, metadata);
			}
		}
	}
	return metadata;
}

private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
	if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
		return InjectionMetadata.EMPTY;
	}

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

	do {
		// 构建currElements,用来存储符合条件的数据
		final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
		//遍历当前类上所有属性,寻找到存在相关注解的属性
		ReflectionUtils.doWithLocalFields(targetClass, field -> {
			//findAutowiredAnnotation方法就是在遍历autowiredAnnotationTypes,判断参数或方法是否被autowiredAnnotationTypes里面的注解修饰,有就直接返回了。
			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));
			}
		});

		//遍历当前类上所有方法,寻找到存在相关注解的属性且非静态方法,然后封装为AutowiredMethodElement后返回
		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);
					}
				}
				// 获取required参数
				boolean required = determineRequiredStatus(ann);
				PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
				// 添加到currElements
				currElements.add(new AutowiredMethodElement(method, required, pd));
			}
		});

		elements.addAll(0, currElements);
		//注入依赖注入一并处理当前父类上标注的相关依赖注入点
		targetClass = targetClass.getSuperclass();
	}
	// 向上遍历,直到父类为Object为止。
	while (targetClass != null && targetClass != Object.class);
	//创建一个InjectionMetadata返回,InjectionMetadata管理当前bean中所有依赖注入点
	return InjectionMetadata.forElements(elements, clazz);
}


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);
		}
	}
	this.checkedElements = checkedElements;
}

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
	//后续依赖注入只会对checkedElements集合中的依赖注入点进行处理
	Collection<InjectedElement> checkedElements = this.checkedElements;
	Collection<InjectedElement> elementsToIterate =
			(checkedElements != null ? checkedElements : this.injectedElements);
	if (!elementsToIterate.isEmpty()) {
		for (InjectedElement element : elementsToIterate) {
			element.inject(target, beanName, pvs);
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值