用Spring Boot配置属性的实例教程

197 阅读4分钟

学习使用 @PropertySource, @值@配置属性注解来注册属性文件并将属性值注入Spring boot应用程序的配置中。

1.用*@PropertySource*注册属性文件

@PropertySource注解用于注册Spring应用程序中的属性文件。

1.1.Spring Boot自动加载application.properties

默认情况下,Spring Boot在启动时自动加载application.properties。我们可以使用*@Value注解来访问application.*properties中定义的属性。

让我们假设我们有以下*application.*properties文件。

application.name=Demo App

如果我们要在Spring*@Component中访问这个属性,我们可以使用@Value*注解。

@Component
//This is optional as Spring boot loads application.properties by default
@PropertySource("classpath:application.properties")
public class AppProperties {

  @Value("${application.name}")
  private String appName;
}

除了application.properties之外,Spring boot还会自动加载配置文件的特定属性文件。例如,如果活动的配置文件是dev ,那么Spring Boot将与application.properties文件一起加载application-dev.properties文件。

**如果这两个文件中的值有任何冲突,那么特定于配置文件的文件将获胜。**理想情况下,我们应该在application.properties中指定默认值,并在application-dev.properties文件中用配置文件的特定值来覆盖它们。

1.2.加载自定义属性文件

如果我们想改变Spring Boot默认读取的文件,那么我们可以使用spring.config.name 属性。

export SPRING_CONFIG_NAME=foo

现在,当我们运行spring boot应用程序时,它将加载foo.properties文件中的所有属性。

如果我们有不同的属性文件或多个属性文件,那么我们可以明确使用@PropertySources 注解来指定这些属性文件。在这种情况下,指定application.properties也是可选的。


@Component
@PropertySources({
    @PropertySource("classpath:jms.properties"),
    @PropertySource("classpath:datasource.properties")
})
public class AppProperties {
	//...
}

1.3.重复的属性解析

这一点很重要,如果有两个或更多的属性具有相同的名称,那么属性值将从最后出现的属性文件中选择

重复的属性值不会引起任何异常。

2.用*@Value*注入属性值

@Value在字段或方法/构造函数参数级别使用,用从属性文件中填充的默认值表达式来初始化字段。

  • SpEL(Spring Expression Language)表达式可以使用#{systemProperties.myProp} 语法来注入值。
  • 属性值可以使用${my.app.myProp} 风格的属性占位符来注入。

另外,我们可以给属性键分配一个默认值。这有助于防止在属性文件中缺少或找不到属性键时出现异常。

@Component
@PropertySources({
    @PropertySource("classpath:jms.properties"),
    @PropertySource("classpath:datasource.properties")
})
public class AppProperties {

  @Value("${application.name:My App}")
  private String appName;

  @Value("${spring.datasource.url}")
  private String datasourceUrl;
}

要在一个字符串数组或列表中插入一个 值的列表,我们可以使用下面的例子。作为参考,属性名称和值是。

app.environments=local,dev,test,prod

默认情况下,支持将这些值注入字符串数组中。

@Value("${app.environments}")
private String[] environments;

要将这些值注入到List中,我们需要使用SpEL语法。

@Value("#{'${app.environments}'.split(',')}")
private List<String> environmentsList;

3.用*@ConfigurationProperties*把字段和属性值绑定起来

@ConfigurationProperties ,用于将Bean中的成员字段与属性文件中定义的属性值绑定。绑定是通过在被注释的类上调用设置器来进行的,或者,如果使用@ConstructorBinding ,则通过绑定到构造器参数。

注意,与@Value 相反,由于属性值被外部化,SpEL表达式不被评估。

例如,假设我们在application.properties 文件中拥有以下属性。

spring.datasource.url=jdbc:h2:file:C:/temp/test
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.dialect=org.hibernate.dialect.H2Dialect

为了在类的字段中绑定这些属性,我们需要创建与属性名称完全相同的字段。另外,我们必须提到prefix ,如果有的话。

@Data
@Component
@ConfigurationProperties(prefix = "spring.datasource")
public class DatasourceProps {

  private String url;
  private String username;
  private String password;
  private String driverClassName;
  private String dialect;
}

如果上述属性是一个单独文件datasource.properties的一部分,那么我们可以使用@PropertySource 来指定属性文件名。

@Data
@Component
@PropertySource("classpath:datasource.properties")
@ConfigurationProperties(prefix = "spring.datasource")
public class DatasourceProps {

  //fields
}

4.验证属性值

首先在项目中导入spring-boot-starter-validation 模块。这个模块导入了*hibernate-validator*项目,实现了JSR-303规范。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

为了验证字段与属性的绑定,我们可以使用@Validated 注释。它是JSR-303的@Valid 的一个变种,支持验证组的规范。

除了*@Validated之外,我们还需要使用javax.validation.constraints注解对字段应用特定的约束。**如果这些验证中的任何一个失败了,那么应用程序就会以IllegalStateException*形式启动失败**。

@Data
@Component
@Validated
public class AppProperties {

  @NotEmpty
  @Value("${application.name}")
  private String appName;

  @NotEmpty
  @Value("${spring.datasource.url}")
  private String datasourceUrl;
}

5.包括额外的配置文件

为了包括额外的属性文件,我们可以在application.propertiesapplication.yml 文件中使用spring.config.import 属性。导入文件在被发现时被处理,并被视为附加文件,紧接着插入到声明导入的文件下面。

例如,我们可以在application.properties文件中拥有以下导入语句。

application.name=Demo App
spring.config.import=optional:file:./dev.properties

上述导入将尝试搜索并导入当前工作目录中的dev.properties文件。如果该文件被找到,那么它的值将优先于触发导入的文件。如果没有找到该文件,则不会报告错误。

注意,spring.config.import 语句在现有属性文件中的位置并不重要。它总是会产生相同的结果,如上所述。

如果我们指定了多个位置,那么所有的位置将按照它们被定义的顺序进行处理,后面的导入将被优先考虑。我们还可以指定一个包含多个属性文件的目录。

spring.config.import=classpath:datasource.properties,
								 classpath:mysql-properties.yml,
								optional:file:./cloud-deployment.properties,
								 classpath:test-properties/

如果一个目录被导入,那么加载的文件将按字母顺序排序。如果我们需要不同的顺序,那么我们应该把每个位置作为一个单独的导入列出来。

spring.config.import 属性也可以使用服务器启动参数来设置。

$ java -jar myproject.jar --spring.config.import=\
    classpath:datasource.properties,\
    classpath:mysql-properties.properties,\
    optional:file:./cloud-deployment.properties,\
    classpath:test-properties/

7.总结

在本教程中,我们学会了使用*@PropertySource@PropertySources注解导入和注册默认属性文件以及多个自定义属性文件。我们学会了使用@ConfigurationProperties*注解将字段与属性值绑定。

我们学会了在应用程序启动时验证属性值,甚至在没有找到相应的属性名称时指定可选的值。

学习愉快!!

源代码在Github上