Spring 工具类 PropertyResourceConfigurer(抽象基类)

概述

Spring PropertyResourceConfigurer是一个抽象基类,继承自PropertiesLoaderSupport,并实现了接口BeanFactoryPostProcessor。它抽象了容器启动时,BeanFactory后置处理阶段对容器中所有bean定义中的属性进行配置的一般逻辑,属性配置所使用的属性来源是基类PropertiesLoaderSupport方法所规定的那些属性。

PropertyResourceConfigurer有两个实现子类:

  • PropertyOverrideConfigurer
    用于处理"beanName.property=value"这种风格的属性值覆盖,将属性对象中的属性"推送(push)"到bean定义中
  • PropertyPlaceholderConfigurer
    用于处理bean定义中"${name}"这样的占位符解析,从属性对象中"拉取(pull)"到bean定义的属性值中

PropertyResourceConfigurer 所在包 : org.springframework.beans.factory.config

PropertyResourceConfigurer有关的类层级关系 :
Spring 工具类 PropertyResourceConfigurer(抽象基类)

源代码解析

方法postProcessBeanFactory(beanFactory)

PropertyResourceConfigurer所抽象的逻辑主要体现在其方法 postProcessBeanFactory :

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) 
		throws BeansException {
		try {
          // 合并本地属性和外部指定的属性文件资源中的属性  
			Properties mergedProps = mergeProperties();

			// Convert the merged properties, if necessary.
          // 将属性的值做转换(仅在必要的时候做)  
			convertProperties(mergedProps);

			// Let the subclass process the properties.
          // 对容器中的每个bean定义进行处理,也就是替换每个bean定义中的属性中的占位符  
			processProperties(beanFactory, mergedProps);
		}
		catch (IOException ex) {
			throw new BeanInitializationException("Could not load properties", ex);
		}
	}

方法postProcessBeanFactory使用到了三个方法 :

  1. mergeProperties()
    该方法由基类PropertiesLoaderSupport提供缺省实现,用于合并本地属性和外来属性为一个Properties对象;
  2. convertProperties(mergedProps)
    该方法由PropertyResourceConfigurer自身提供缺省实现,用于对属性值做必要的转换处理,缺省不做任何处理;
  3. processProperties(beanFactory, mergedProps)
    该方法由PropertyResourceConfigurer定义为抽象方法,所以需要由实现子类为其提供具体实现。不过其目的很明确,是对容器中每个bean定义中的属性进行处理。但具体处理是什么,就要看实现子类自身的设计目的了。比如实现子类PropertyOverrideConfigurer和实现子类PropertyPlaceholderConfigurer就分别有自己的bean定义属性处理逻辑。

方法 convertProperties(mergedProps)

	// 对指定属性对象中的属性值进行必要的转换
    protected void convertProperties(Properties props) {
		Enumeration<?> propertyNames = props.propertyNames();
		while (propertyNames.hasMoreElements()) {
			String propertyName = (String) propertyNames.nextElement();
			String propertyValue = props.getProperty(propertyName);
			String convertedValue = convertProperty(propertyName, propertyValue);
			if (!ObjectUtils.nullSafeEquals(propertyValue, convertedValue)) {
				props.setProperty(propertyName, convertedValue);
			}
		}
	}

	// 对指定名称的属性的属性值进行必要的转换
	protected String convertProperty(String propertyName, String propertyValue) {
		return convertPropertyValue(propertyValue);
	}

	// 对属性值的必要转换,这是一个缺省实现,不做任何转换直接返回原值,实现类可以覆盖该方法
	protected String convertPropertyValue(String originalValue) {
		return originalValue;
	}

方法 processProperties(beanFactory, mergedProps)

这是一个抽象方法定义,约定对容器beanFactory中所有的bean定义进行属性处理,属性值解析来源是mergedProps,实现子类必须对该方法提供实现。

总结

从上面的分析可以看出,PropertyResourceConfigurer自身主要是抽象了对容器中所有bean定义的属性进行处理的一般逻辑,实现在接口BeanFactoryPostProcessor所定义的方法postProcessBeanFactory中,这样容器启动时,bean容器的后置处理阶段,所有bean定义的属性都会被当前configure进行处理,处理时所使用的属性来源自当前configure基类PropertiesLoaderSupport所约定的那些属性,至于做什么样的处理,由当前configure的具体实现类,也就是PropertyResourceConfigurer的实现子类自己提供实现。

参考文章

Spring PropertiesLoaderSupport 源代码分析