spring 和 spring boot 中的属性配置方式

目录
  • 在xml中注册属性文件
    • 多个
  • 通过java注解方式注册属性文件
  • 使用及注入属性
    • 属性搜索优先级
  • spring boot 属性加载
    • application.properties – 缺省属性文件
    • 特定环境属性文件
    • 特定测试属性文件
    • @TestPropertySource注解
    • 层次属性
    • YAML 文件
    • 命令行传入属性
    • 环境变量属性
    • 随机属性值
    • 其他类型的属性源
  • spring配置实现
  • 多层级上下文中属性加载
    • 属性文件通过定义xml中
    • 属性文件通过@PropertySource定义在java中
  • 总结

本文我们介绍如何在spring中配置和应用属性——通过xml的 或java Configuration 的@PropertySource。

在Spring 3.1之前,将新的属性文件添加到Spring中及使用属性值并不是那么灵活和健壮。从Spring 3.1开始,新的Environment 和 PropertySource 抽象已经简化整个过程。

在xml中注册属性文件

通过在xml增加

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xsi:schemaLocation="
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-4.2.xsd">
      <context:property-placeholder location="classpath:foo.properties" />
</beans>

foo.properties文件可以放在/src/main/resources文件夹中,即运行时类路径。

多个

如果在Spring上下文中出现了多个 元素,那么应该遵循以下几个最佳实践:

  • 需指定order属性来确定spring处理顺序
  • 需要引用其他原始属性元素应该增加ignore-unresolvable= “true”,使解析机制先不抛出异常的情况下继续加载其他配置。

通过java注解方式注册属性文件

Spring 3.1 引入新的 @PropertySource 注解,可以方便地给spring environment中添加property source。该注解与基于Java Configuration 方式配置的@Configuration注解一起使用:

@Configuration
@PropertySource("classpath:foo.properties")
public class PropertiesWithJavaConfig {
    //...
}

另一个非常有用的注册方式为使用占位符方式实现运行时动态选择属性文件,示例如下:

@PropertySource({
  "classpath:persistence-${envTarget:mysql}.properties"
})
…

使用及注入属性

直接通过 @Value 注解注入属性:

@Value( "${jdbc.url}" )
private String jdbcUrl;

也可以指定缺省值:

@Value( "${jdbc.url:aDefaultUrl}" )
private String jdbcUrl;

在 Spring XML configuration使用属性:

<bean id="dataSource">
  <property name="url" value="${jdbc.url}" />
</bean>

旧的 PropertyPlaceholderConfigurer 和新的 PropertySourcesPlaceholderConfigurer(Spring 3.1 中引入)都可以解析xml bean定义和@value注解中的 ${…} 占位符 。

最后,使用新的Environment API可以获取属性值:

@Autowired
private Environment env;
...
dataSource.setUrl(env.getProperty("jdbc.url"));

特别需要注意的是,使用不会暴露属性给 Spring Environment,这意味这下面代码会返回null:

env.getProperty("key.something")

属性搜索优先级

spring4中,默认local properties文件最后加载,environment Properties和system Properties之后。local properties是通过PropertiesLoaderSupport 类的API方法 (setProperties, setLocation, etc)手工或编程方式配置的。

这种机制可以通过设置PropertySourcesPlaceholderConfigurer类的localOverride 属性进行修改,值为true允许local properties覆盖spring系统加载的。

spring3.0之前,PropertyPlaceholderConfigurer 类尝试在手工定义源和System Properties两个地方查找,查找顺序也可以通过设置systemPropertiesMode属性进行配置:

  • never – 总不检查 system properties
  • fallback (default) – 如果指定的properties files查找不到,则检查 system properties
  • override – 先检查system properties,然后再尝试指定的properties files。这允许system properties覆盖任何其他属性源。

最后需注意,如果在两个或多个通过@PropertySource定义了属性,那么最后一个定义优先级最高并覆盖以前的定义。这使得准确的属性值难以预测,所以如果覆盖不满足需求,那么可以重写PropertySource API。

spring boot 属性加载

在我们进入更高级的属性配置之前,让我们先看看Spring Boot中属性加载的新特性。

总的来说与标准Spring相比,这种新支持的配置更少,当然这是Spring Boot的主要目标之一。

application.properties – 缺省属性文件

spring boot 应用是典型基于配置文件规范约定。我们可以简单地放“application.properties” 文件在“src/main/resources”目录中,spring boot会自定监测,我们能在其中放入任何属性。

通过使用缺省文件,我们无须显示注册PropertySource并指定属性文件路径。我们也可以在运行时使用环境变量属性指定不同的属性配置文件:

java -jar app.jar --spring.config.location=classpath:/another-location.properties

特定环境属性文件

如果我们需要针对不同环境,spring boot内置机制可以满足。我们可以在“src/main/resources”目录中定义“application-environment.properties” 文件,然后设置spring profile与environment名称一致。

例如,如果我们定义“staging” 环境变量,则我们必须定义staging profile,然后定义application-staging.properties属性文件。

特定环境属性文件加载优先级高于缺省属性文件。注意,默认文件仍然会被加载,只是当有属性冲突时,特定环境属性文件优先。

特定测试属性文件

在应用测试阶段,我们可能需要不同的属性值。Spring Boot通过在测试运行期间查找“src/test/resources”目录中的属性文件来处理这个问题。同样,默认属性仍然会被加载,但是如果发生冲突,将会覆盖这些属性。

@TestPropertySource注解

如果需要更细粒度控制测试属性,我们可以使用@TestPropertySource注解。其可以设置给测试上下文设置测试属性,比缺省属性源优先级高:

@ContextConfiguration
@TestPropertySource("/my-test.properties")
public class IntegrationTests {
    // tests
}

如果我们不想使用文件,也直接指定名称和值:

@ContextConfiguration
@TestPropertySource("foo=bar", "bar=foo")
public class IntegrationTests {
    // tests
}

也可以通过@SpringBootTest注解,指定相应properties参数值达到同样效果:

@SpringBootTest(properties = {"foo=bar", "bar=foo"})
public class IntegrationTests {
    // tests
}

层次属性

如果属性按分组形式配置,可以使用 @ConfigurationProperties注解,其会按照对象图方式映射这些分层组织属性。下面示例看看数据库连接配置属性:

database.url=jdbc:postgresql:/localhost:5432/instance
database.username=foo
database.password=bar

然后使用注解映射至数据库对象:

@ConfigurationProperties(prefix = "database")
public class Database {
    String url;
    String username;
    String password;
    // standard getters and setters
}

spring boot 在配置方法中再次应用了基于约定原则,自动映射属性值对象字段,我们仅需提供属性前缀即可。

YAML 文件

YAML文件也支持。

同样名称规则可以应用至测试规范、environmet规范以及缺省属性文件。仅文件扩展名不同以及需提供SnakeYAML依赖。

YAML对层次属性存储特别方便,下面的属性文件:

database.url=jdbc:postgresql:/localhost:5432/instance
database.username=foo
database.password=bar
secret: foo

对应的YAML文件为:

database:
  url: jdbc:postgresql:/localhost:5432/instance
  username: foo
  password: bar
secret: foo

需要注意的是YAML文件不支持使用@PropertySource注解,所以如果使用该注解则必须使用属性文件。

命令行传入属性

相对于使用文件,属性也可以直接通过命令行进行传递:

java -jar app.jar --property="value"

你也能通过系统属性实现,需要在-jar命令之前提供:

java -Dproperty.name="value" -jar app.jar

环境变量属性

spring boot也能监测环境变量,效果与属性一样:

export name=value
java -jar app.jar

随机属性值

如果属性值不确定,RandomValuePropertySource 可以实现给属性赋随机值:

random.number=${random.int}
random.long=${random.long}
random.uuid=${random.uuid}

其他类型的属性源

spring boot 支持很多属性源,实现较好顺序及合理覆盖。其官方文档可以参阅。

spring配置实现

  • spring3.1之前

spring3.1引入注解,可以方便地定义属性源,在此之前,xml配置是必须的。 xml元素自动在spring上下文中注册新的PropertyPlaceholderConfigurer bean。为了向后兼容,在spring3.1及之后版本中,如果XSD schemas不升级到新的3.1 XSD版本,仍然会创建相应bean。

  • spring3.1之后

从spring3.1起,XML 元素不再注册旧的PropertyPlaceholderConfigurer 类,代替引入PropertySourcesPlaceholderConfigurer类,新的类可以实现更灵活地和Environment 和 PropertySource机制进行交互。

对3.1之后版本,应该应用新的标准。

多层级上下文中属性加载

当web应用有父和子上下文时,属性如何加载是很常见的问题。父上下文有一些通用的核心功能和bean,并包括一个或多个子上下文,可能包含servlet特定的bean。

这种场景下,如何最佳方式定义属性文件并引入到各自的上下文中?以及如何在spring中以最佳方式获取这些属性,下面分类进行说明:

属性文件通过定义xml中

如果文件定义在父上下文:

  • @Value 在子上下文 : 否
  • @Value 在父上下文 : 是

如果文件定义在子上下文:

  • @Value 在子上下文 : 是
  • @Value 在父上下文 : 否

总之如上所述,没有暴露属性给environment,所以environment.getProperty在上下文中不工作。

属性文件通过@PropertySource定义在java中

如果文件定义在父上下文:

  • @Value 在子上下文 : 是
  • @Value 在父上下文 : 是
  • environment.getProperty 在子上下文: 是
  • environment.getProperty 在父上下文: 是

如果文件定义在子上下文:

  • @Value 在子上下文 : 是
  • @Value 在父上下文 : 否
  • environment.getProperty 在子上下文: 是
  • environment.getProperty 在父上下文: 否

总结

本文通过几个示例说明了spring中加载属性机制。希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 浅谈Spring Boot 属性配置和自定义属性配置

    在使用spring boot过程中,可以发现项目中只需要极少的配置就能完成相应的功能,这归功于spring boot中的模块化配置,在pom.xml中依赖的每个Starter都有默认配置,而这些默认配置足以满足正常的功能开发. 如果需要修改自定义修改默认配置,spring boot 提供了很简便的方法,只需要在application.properties 中添加修改相应的配置.(spring boot启动的时候会读取application.properties这份默认配置) 一.修改默认配置 例

  • Spring Boot读取配置属性常用方法解析

    1. 前言 在Spring Boot项目中我们经常需要读取application.yml配置文件的自定义配置,今天就来罗列一下从yaml读取配置文件的一些常用手段和方法. 2. @Value 首先,会想到使用@Value注解,该注解只能去解析yaml文件中的简单类型,并绑定到对象属性中去. felord: phone: 182******32 def: name: 码农小胖哥 blog: felord.cn we-chat: MSW_623 dev: name: 码农小胖哥 blog: felo

  • spring boot中的properties参数配置详解

    application.properties application.properties是spring boot默认的配置文件,spring boot默认会在以下两个路径搜索并加载这个文件 src\main\resources src\main\resources\config 配置系统参数 在application.properties中可配置一些系统参数,spring boot会自动加载这个参数到相应的功能,如下 #端口,默认为8080 server.port=80 #访问路径,默认为/

  • 详解Spring Boot 属性配置和使用

    spring Boot 允许通过外部配置让你在不同的环境使用同一应用程序的代码,简单说就是可以通过配置文件来注入属性或者修改默认的配置. Spring Boot 支持多种外部配置方式 这些方式优先级如下: 命令行参数 来自java:comp/env的JNDI属性 Java系统属性(System.getProperties()) 操作系统环境变量 RandomValuePropertySource配置的random.*属性值 jar包外部的application-{profile}.propert

  • spring 和 spring boot 中的属性配置方式

    目录 在xml中注册属性文件 多个 通过java注解方式注册属性文件 使用及注入属性 属性搜索优先级 spring boot 属性加载 application.properties – 缺省属性文件 特定环境属性文件 特定测试属性文件 @TestPropertySource注解 层次属性 YAML 文件 命令行传入属性 环境变量属性 随机属性值 其他类型的属性源 spring配置实现 多层级上下文中属性加载 属性文件通过定义xml中 属性文件通过@PropertySource定义在java中 总

  • Spring中Xml属性配置的解析全过程记录

    1 工程概述 1.1 pom文件 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <spring.ver

  • spring+apollo动态获取yaml格式的配置方式

    默认spring装载的都是.properties格式的配置文件,但是有时我们需要定义list或者map类型的配置,那么yaml就具有优势. 以下演示利用apollo来完成自动更新ip白名单的功能 1.重写配置工厂 public class YmlPropertySourceFactory extends DefaultPropertySourceFactory { public PropertySource<?> createPropertySource(String name, Encode

  • Spark三种属性配置方式详解

    随着Spark项目的逐渐成熟, 越来越多的可配置参数被添加到Spark中来.在Spark中提供了三个地方用于配置: 1.Spark properties:这个可以控制应用程序的绝大部分属性.并且可以通过 SparkConf对象或者Java 系统属性进行设置: 2.环境变量(Environment variables):这个可以分别对每台机器进行相应的设置,比如IP.这个可以在每台机器的$SPARK_HOME/ conf/spark-env.sh脚本中进行设置: 3.日志:所有的日志相关的属性可以

  • Vue配置文件中的proxy配置方式详解

    1. 这里以axios发请求为例 axios.get("/abc/def"); axios.get("/abc/ghi"); axios.post("/abc/jkm"); axios发送的请求是本地的服务器地址拼接上发送的请求,如 http://localhost:8080/abc/def 2. 如果发送的请求都以 /abc 开头,那么我们就可以在proxy中进行服务器代理配置. devServer: { proxy: { "/abc

  • Spring Boot中的属性绑定的实现

    之前翻译了一篇不怎么样的文章,主要是翻译的水平有限,自己翻译的云里雾里,发现平时只会有@ConfigurationProperties注解,对SpringBoot强大的属性绑定知之甚少,所以以那篇文章为线索,重新学习了一遍. @ConfigurationProperties 在使用的时候,我们往往只关心两件事,属性怎么绑定,即属性文件中的值和配置类中字段的映射关系:其次是类实例化的时机.故而衍生开来ConfigurationProperties有三种用法. @Component + @Confi

  • 全面解读Spring Boot 中的Profile配置体系

    Pre 配置体系是基于 Spring Boot 框架开发应用程序的基础,而自动配置也是该框架的核心功能之一,梳理使用 Spring Boot 配置体系的系统方法. 接下来,我们为这个代码工程添加一些支持 RESTful 风格的 HTTP 端点,在这里我们同样创建一个 CustomerController 类,如下所示 @RestController @RequestMapping(value="customers") public class CustomerController {

  • Spring中Properties的配置方式

    对 Spring 里面的 Properties 不理解的开发者可能会觉得有点乱,主要是因为配置方式很多种,使用方式也很多种. 本文不是原理分析.源码分析文章,只是希望可以帮助读者更好地理解和使用 Spring Properties. Properties 的使用 本文的读者都是使用过 Spring 的,先来看看 Properties 是怎么使用的,Spring 中常用的有以下几种使用方式: 1. 在 xml 配置文件中使用 即自动替换 ${} 里面的值. <bean id="xxx&quo

  • Vue中的ESLint配置方式

    目录 说说Vue项目中添加ESLint的规则 第一步:安装 第二步:配置.eslintrc文件 第三步:如图配置 用惯了组里统一的代码风格,再看默认的vue项目代码很是别扭,记录下ESLint配置,以后直接copy paste,美滋滋 官网:https://eslint.org/docs/rules/ ESLint配置方式 ESLint有三种配置方式,一般自定义规则较少时,选第2种:自定义配置很多,建议第1种:第3种常用于对某句代码禁用eslint. 1.在package.json中通过esli

  • Vue项目中对index.html中BASE_URL的配置方式

    目录 Vue项目对index.html中BASE_URL的配置 问题 解决 Vue项目url中的<%= BASE_URL %> Vue项目对index.html中BASE_URL的配置 问题 有时候后端配置资源的默认访问路径的时候,可能会与前端打包时配置的默认根路径有所差异 比如:后端要访问静态资源的根路径为/static,而一般情况下,我们项目的vue.config.js中对BAES_URL的配置是/,或者不做配置,因为它默认的值也是/ 这个路径决定了我们的前端项目打包后获取静态资源的默认的

随机推荐