Spring PropertyResolver 占位符解析API 介绍

Posted binarylei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring PropertyResolver 占位符解析API 介绍相关的知识,希望对你有一定的参考价值。

Spring PropertyResolver 占位符解析(一)API 介绍

Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html)

Spring 3.1 提供了新的占位符解析器 PropertyResolver,默认实现为 PropertySourcesPropertyResolver。相关文章如下:

  1. Spring PropertyResolver 占位符解析(一)API 介绍
  2. Spring PropertyResolver 占位符解析(二)源码分析

一、PropertyResolver API

PropertyResolver 的默认实现是 PropertySourcesPropertyResolver,Environment 实际上也是委托 PropertySourcesPropertyResolver 完成 占位符的解析和类型转换。 类型转换又是委托 ConversionService 完成的。

public interface PropertyResolver {
    // 1. contains
    boolean containsProperty(String key);

    // 2.1 获取指定 key,不存在可以指定默认值,也可以抛出异常
    String getProperty(String key);
    String getProperty(String key, String defaultValue);

    // 2.2 类型转换,委托 ConversionService 完成
    <T> T getProperty(String key, Class<T> targetType);
    <T> T getProperty(String key, Class<T> targetType, T defaultValue);

    String getRequiredProperty(String key) throws IllegalStateException;
    <T> T getRequiredProperty(String key, Class<T> targetType) throws IllegalStateException;

    // 3. 解析占位符 ${key}
    String resolvePlaceholders(String text);
    String resolveRequiredPlaceholders(String text) throws IllegalArgumentException;
}

PropertyResolver 组件完成了两件事:一是占位符解析 ${key};二是类型转换。使用方法如下:

@Test
public void PropertyResolverTest() {
    PropertySource propertySource = new MapPropertySource("source",
            Collections.singletonMap("name", "binarylei"));
    MutablePropertySources propertySources = new MutablePropertySources();
    propertySources.addFirst(propertySource);
    PropertyResolver propertyResolver = new PropertySourcesPropertyResolver(propertySources);

    Assert.assertEquals("binarylei", propertyResolver.getProperty("name"));
    Assert.assertEquals("name is binarylei", propertyResolver.resolvePlaceholders("name is ${name}"));
}

二、Spring 是如何使用的

(1) xml 配置

<context:property-placeholder   
    location="属性文件,多个之间逗号分隔"  
    file-encoding="文件编码"  
    ignore-resource-not-found="是否忽略找不到的属性文件"  
    ignore-unresolvable="是否忽略解析不到的属性,如果不忽略,找不到将抛出异常"  
    properties-ref="本地Properties配置"  
    local-override="是否本地覆盖模式,即如果true,那么properties-ref的属性将覆盖location加载的属性,否则相反"  
    system-properties-mode="系统属性模式,默认ENVIRONMENT(表示先找ENVIRONMENT,再找properties-ref/location的),NEVER:表示永远不用ENVIRONMENT的,OVERRIDE类似于ENVIRONMENT"  
    order="顺序"  
/>  
  • location:表示属性文件位置,多个之间通过如逗号/分号等分隔;
  • file-encoding:文件编码;
  • ignore-resource-not-found:如果属性文件找不到,是否忽略,默认 false,即不忽略,找不到将抛出异常
  • ignore-unresolvable:是否忽略解析不到的属性,如果不忽略,找不到将抛出异常
  • properties-ref:本地 java.util.Properties 配置
  • local-override:是否本地覆盖模式,即如果 true,那么 properties-ref 的属性将覆盖 location 加载的属性
  • system-properties-mode:系统属性模式,ENVIRONMENT(默认),NEVER,OVERRIDE
    1. ENVIRONMENT:将使用 Spring 3.1 提供的 PropertySourcesPlaceholderConfigurer,其他情况使用 Spring 3.1 之前的 PropertyPlaceholderConfigurer。如果是本地覆盖模式:那么查找顺序是:properties-ref、location、environment,否则正好反过来;
    2. OVERRIDE: PropertyPlaceholderConfigurer 使用,因为在 spring 3.1 之前版本是没有 Enviroment 的,所以 OVERRIDE 是 spring 3.1 之前版本的 Environment。如果是本地覆盖模式:那么查找顺序是:properties-ref、location、System.getProperty(), System.getenv(),否则正好反过来;
    3. NEVER:只查找 properties-ref、location;
  • order:当配置多个context:property-placeholder/时的查找顺序,关于顺序问题请参考:<http://www.iteye.com/topic/1131688 >

(2) 注解配置

@Configuration  
@PropertySource(value = "classpath:resources.properties", ignoreResourceNotFound = false)  
public class AppConfig {    
    // 如果想进行 Bean 属性的占位符替换,需要注册 PropertySourcesPlaceholderConfigurer
    @Bean  
    public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {  
        return new PropertySourcesPlaceholderConfigurer();  
    }   
} 

如上配置等价于 XML 中的 context:property-placeholder/ 配置。

(3) 占位符替换

使用 Environment 属性替换,如:

<context:property-placeholder location="classpath:${env}/resources.properties"/>  
<context:component-scan base-package="com.sishuok.${package}"/> 
<import resource="classpath:${env}/ctx.xml"/>

同样可以在注解中使用占位符。

@PropertySource(value = "classpath:${env}/resources.properties")
@ComponentScan(basePackages = "com.sishuok.${package}")
@ImportResource(value = {"classpath:${env}/cfg.xml"})
@Value("${env}")   
new ClassPathXmlApplicationContext("classpath:${env}/cfg.xml")

参考:

  1. 《pring3.1新属性管理API:PropertySource、Environment、Profile》:https://jinnianshilongnian.iteye.com/blog/2000183

每天用心记录一点点。内容也许不重要,但习惯很重要!

以上是关于Spring PropertyResolver 占位符解析API 介绍的主要内容,如果未能解决你的问题,请参考以下文章

Spring读源码系列番外篇---02---PropertyResolver的结构体系剖析---上

Spring读源码系列番外篇---03---PropertyResolver的结构体系剖析---下

spring源码解析---占位符解析替换

yml文件常见的几种读取方式

5种高大上的yml文件读取方式,你知道吗?

请教css高手:子容器高度占满父容器高度应该怎么做?