我们详细说明一下那些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抛出异常
privateprivate 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
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 } } } }