我是靠谱客的博主 俭朴山水,最近开发中收集的这篇文章主要介绍Spring中那些BeanFactoryPostProcessors详解(二)【1】PropertySourcesPlaceholderConfigurer【2】ConfigurationPropertiesBeanDefinitionValidator【3】EventListenerMethodProcessor【4】PreserveErrorControllerTargetClassPostProcessor,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

关联博文:
Spring中那些BeanFactoryPostProcessors详解(一)
Spring中那些BeanFactoryPostProcessors详解(二)

本文是对Spring中refresh分析之invokeBeanFactoryPostProcessors方法详解的一个补充,我们详细说明一下那些BeanFactoryPostProcessor在invokeBeanFactoryPostProcessors方法中的作用。

【1】PropertySourcesPlaceholderConfigurer

其主要是用来解析BeanDefinition中的${...}占位符,使用propertySources中的值替代。

protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
		final ConfigurablePropertyResolver propertyResolver) throws BeansException {

	// ${
	propertyResolver.setPlaceholderPrefix(this.placeholderPrefix);
	// }
	propertyResolver.setPlaceholderSuffix(this.placeholderSuffix);
	// DEFAULT_VALUE_SEPARATOR = ":"
	propertyResolver.setValueSeparator(this.valueSeparator);

	StringValueResolver valueResolver = strVal -> {
		String resolved = (this.ignoreUnresolvablePlaceholders ?
				propertyResolver.resolvePlaceholders(strVal) :
				propertyResolver.resolveRequiredPlaceholders(strVal));
		if (this.trimValues) {
			resolved = resolved.trim();
		}
		return (resolved.equals(this.nullValue) ? null : resolved);
	};

	doProcessProperties(beanFactoryToProcess, valueResolver);
}

本文这里的propertySources如下所示:
在这里插入图片描述

【2】ConfigurationPropertiesBeanDefinitionValidator

BeanDefinition校验器,验证常规bean定义没有创建ConstructorBinding beans。

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
	for (String beanName : beanFactory.getBeanDefinitionNames()) {
		if (!(beanFactory.containsSingleton(beanName) || isValueObjectBeanDefinition(beanFactory, beanName))) {
			validate(beanFactory, beanName);
		}
	}
}

如果当前bean不是单例bean且对应BeanDefinition不是ConfigurationPropertiesValueObjectBeanDefinition,那么触发validate方法。

ConfigurationPropertiesValueObjectBeanDefinition用于注册在创建时绑定的@ConfigurationProperties值对象bean。

校验方法如下所示对BindMethod做了校验,如果是VALUE_OBJECT抛出异常

private void validate(ConfigurableListableBeanFactory beanFactory, String beanName) {
	try {
		Class<?> beanClass = beanFactory.getType(beanName, false);
		if (beanClass != null && BindMethod.forType(beanClass) == BindMethod.VALUE_OBJECT) {
			throw new BeanCreationException(beanName,
					"@EnableConfigurationProperties or @ConfigurationPropertiesScan must be used to add "
							+ "@ConstructorBinding type " + beanClass.getName());
		}
	}
	catch (CannotLoadBeanClassException ex) {
		// Ignore
	}

}

BindMethod有两种:JAVA_BEAN对应getter/setter绑定,VALUE_OBJECT对应构造器绑定。

【3】EventListenerMethodProcessor

这个玩意主要是对@EventListener方法做处理,其实现了SmartInitializingSingleton, ApplicationContextAware, BeanFactoryPostProcessor三个接口。

我们要对SmartInitializingSingleton有概念哦,当所有单例bean实例化后,会遍历触发SmartInitializingSingleton实例的afterSingletonsInstantiated方法。

postProcessBeanFactory方法如下所示,对EventListenerFactory进行排序然后赋予EventListenerMethodProcessor的成员List<EventListenerFactory> eventListenerFactories

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	this.beanFactory = beanFactory;

//获取容器中的EventListenerFactory
	Map<String, EventListenerFactory> beans = beanFactory.getBeansOfType(EventListenerFactory.class, false, false);
	List<EventListenerFactory> factories = new ArrayList<>(beans.values());
	//对其EventListenerFactory见排序
	AnnotationAwareOrderComparator.sort(factories);
	//排序后的factories赋予eventListenerFactories 
	this.eventListenerFactories = factories;
}

在这里插入图片描述

其afterSingletonsInstantiated方法则是会将当前bean中标注了@EventListener的方法封装为一个ApplicationListener(通常是ApplicationListenerMethodAdapter)。

【4】PreserveErrorControllerTargetClassPostProcessor

其是ErrorMvcAutoConfiguration的内部类确保在使用AOP时保留ErrorController MVC bean的目标类。

static class PreserveErrorControllerTargetClassPostProcessor implements BeanFactoryPostProcessor {

		@Override
		public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		//获取ErrorController
			String[] errorControllerBeans = beanFactory.getBeanNamesForType(ErrorController.class, false, false);
//遍历设置属性org.springframework.aop.framework.autoproxy.AutoProxyUtils.preserveTargetClass为true;
			for (String errorControllerBean : errorControllerBeans) {
				try {
					beanFactory.getBeanDefinition(errorControllerBean)
							.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
				}
				catch (Throwable ex) {
					// Ignore
				}
			}
		}
	}

最后

以上就是俭朴山水为你收集整理的Spring中那些BeanFactoryPostProcessors详解(二)【1】PropertySourcesPlaceholderConfigurer【2】ConfigurationPropertiesBeanDefinitionValidator【3】EventListenerMethodProcessor【4】PreserveErrorControllerTargetClassPostProcessor的全部内容,希望文章能够帮你解决Spring中那些BeanFactoryPostProcessors详解(二)【1】PropertySourcesPlaceholderConfigurer【2】ConfigurationPropertiesBeanDefinitionValidator【3】EventListenerMethodProcessor【4】PreserveErrorControllerTargetClassPostProcessor所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部