【SpringBoot笔记4】外置配置

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hbtj_1216/article/details/84944378

SpringBoot允许你外置化项目的配置信息,你可以使用properties文件、YAML文件、环境变量、命令行参数来设置配置信息。

1 优先级

SpringBoot提供多种外部配置方式,这些方式的优先级如下(由高到低):

  1. 命令行参数
  2. 来自java:comp/envJNDI属性
  3. Java系统属性(System.getProperties()
  4. 操作系统环境变量
  5. RandomValuePropertySource配置的random.*属性值
  6. jar包外部的application-{profile}.propertiesapplication.yml(带spring.profile)配置文件
  7. jar包内部的application-{profile}.propertiesapplication.yml(带spring.profile)配置文件
  8. jar包外部的application.propertiesapplication.yml(不带spring.profile)配置文件
  9. jar包内部的application.propertiesapplication.yml(不带spring.profile)配置文件
  10. @Configuration注解类上的@PropertySource
  11. 通过SpringApplication.setDefaultProperties指定的默认属性

2 使用

2.1 自定义配置

例如,在项目中定义一个类MyBean,它的一个成员变量name的值需要从外部配置文件中读取,可以使用@Value注释:

@Component("myBean")
public class MyBean {

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

${MyBean.name}表示获取变量MyBean.name的值,该变量可以在application.properties文件中定义:

MyBean.name=MyBean-HaHa

2.2 使用SpringBoot提供的随机值

SpringBoot内置了一个RandomValuePropertySource类,提供了生成随机值的功能。我们可以在配置文件中或者代码中直接通过random.*获取SpringBoot提供的随机值。

  • random.value—— 返回一个随机字符串
  • random.int —— 返回一个随机int类型值
  • random.long —— 返回一个随机long类型值
  • random.uuid —— 返回一个随机的uuid
  • random.int(10) —— 返回一个小于10int类型值
  • random.int[1024, 65536] —— 返回一个范围类的int类型值

可以在application.properties配置文件中获取并赋值给自定义的变量:

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

也可以直接在程序中取值:

@Component("myRandom")
public class MyRandom {

    @Value("${random.value}")
    //@Value("${my.secret}")
    private String secret;

    @Value("${random.int}")
    //@Value("${my.number}")
    private Integer number;

    @Value("${random.long}")
    //@Value("${my.bignumber}")
    private Long bigNumber;

    @Value("${random.uuid}")
    //@Value("${my.uuid}")
    private String uuid;

    @Value("${random.int(10)}")
    //@Value("${my.number.less.than.ten}")
    private Integer numberLessThanTen;

    @Value("${random.int[1024,65536]}")
    //@Value("${my.number.in.range}")
    private Integer numberInRange;

    @Override
    public String toString() {
        return "MyRandom{" +
                "secret='" + secret + '\'' +
                ", number=" + number +
                ", bigNumber=" + bigNumber +
                ", uuid='" + uuid + '\'' +
                ", numberLessThanTen=" + numberLessThanTen +
                ", numberInRange=" + numberInRange +
                '}';
    }
}

2.3 访问命令行属性

命令行属性通过java -jar app.jar --name="String" --serverPort=8888来传递。

参数的传递格式为--xxx=XXX

参数名可以使自定义的,也可以是SpringBoot内置的参数名。

如果想禁用命令行传递属性功能,可以使用SpringApplication.setAddCommandLineProperties(false)进行配置。

2.4 使用应用程序的.properties属性文件

2.4.1 优先级顺序

SpringApplication从以下位置中加载application.properties文件到Spring的环境中:

  1. 当前目录的/config子目录

  2. 当前目录

  3. classpath下的/config目录

  4. classpath目录

说明:

(1)1和2中所描述的“当前目录”是指项目打包之后.jar.war包所在的目录,适合生产环境。

(2)3和4是项目中的目录,通常就是指web项目中的src/main/resources/config目录或src/main/resources目录,适合开发环境。

(3)如果4个地方都有配置文件,那么配置生效的优先级从14,搜索配置文件的顺序从41,后加载的会覆盖先加载的。

(4)使用配置文件之后,SpringBoot启动时,会自动把配置信息读取Spring容器中,并覆盖SpringBoot的默认配置。

(5)可以使用YAML.yml)文件替换.properties文件,效果相同。

2.4.2 自定义文件名

如果不喜欢application.properties文件名,可以通过指定spring.config.name环境变量的值来指定读取的属性文件的文件名:

$ java -jar myproject.jar --spring.config.name = myproject

也可以通过spring.config.location环境变量(以逗号分隔的目录位置或文件路径列表)来引用显式位置。

$ java -jar myproject.jar --spring.config.location = classpath:/default.properties,classpath:/override.properties

注意:

spring.config.namespring.config.location被加载的时期非常靠前,因此必须将它们定义为环境属性(通常是OS环境变量,系统属性或命令行参数)。

配置文件生效的优先级顺序如下:

  1. file:./config/
  2. file:./
  3. classpath:/config/
  4. classpath:/

如果通过spring.config.location配置了配置文件的位置,那么将会替换14中的值。例如--spring.config.location = classpath:/custom-config/,file:./custom-config/,则14变为:

  1. file:./custom-config/
  2. classpath:/custom-config/

或者,当使用spring.config.additional-location环境变量来配置自定义位置时,默认的4个配置位置继续保留,并且自定义位置的优先级高于默认位置。例如--spring.config.additional-location = classpath:/custom-config/,file:./custom-config/,则优先级如下:

  1. file:./custom-config/
  2. classpath:/custom-config/
  3. file:./config/
  4. file:./
  5. classpath:/config/
  6. classpath:/

2.4.3 定义特定于配置文件的属性

除了application.properties文件之外,还可以通过约定的命名规则来指定特定环境下的配置文件:application-{profile}.properties

如果没有指定,默认情况下SpringBoot会加载一个名为application-default.properties的文件。

定义的特定环境的配置文件的优先级最高,无论它的位置在哪里。

需要在application.properties文件中通过spring.profiles.active来具体激活一个或多个配置文件,也可以通过spring.profiles.include来使多个配置文件同时生效。

2.5 获取(使用)属性值

2.5.1 使用@Value("${xxx}")

最简单的方式就是通过@Value注解注入属性值。

2.5.2 使用@ConfigurationProperties

SpringBoot可以方便的将属性注入到一个配置对象中。例如:

my.name=Isea533
my.port=8080
my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com

配置对象:

@ConfigurationProperties(prefix="my")
public class Config {
    private String name;
    private Integer port;
    private List<String> servers = new ArrayList<String>();

    public String geName(){
        return this.name;
    }

    public Integer gePort(){
        return this.port;
    }
    public List<String> getServers() {
        return this.servers;
    }
}

SpringBoot会自动将prefix="my"前缀为my的属性注入进来。

SpringBoot会自动转换类型,当使用List的时候需要注意在配置中对List进行初始化!

SpringBoot 还支持嵌套属性注入,例如:

name=isea533
jdbc.username=root
jdbc.password=root

对应的配置类:

@ConfigurationProperties
public class Config {
    
    private String name;
    private Jdbc jdbc;
    
    public Integer gePort(){
        return this.port;
    }
    public Jdbc getJdbc() {
        return this.jdbc;
    }
}

class Jdbc {
    private String username;
    private String password;
    // getter...
}

jdbc开头的属性都会注入到Jdbc对象中。

@Bean方法上使用@ConfigurationPropertiesSpringBoot会将属性注入到返回的对象里面:

@ConfigurationProperties(prefix = "foo")
@Bean
public FooConfig fooConfig() {
    ...
}

2.5.3 属性占位符

SpringBoot在配置文件中还支持属性占位符:

app.name=MyApp
app.description=${app.name} is a Spring Boot application

可以在配置文件中引用前面配置过的属性。

通过形如${app.name:默认名称}方式还可以设置默认值,当找不到引用的属性时,会使用默认值。

2.5.4 属性名匹配规则

例如有如下配置对象:

@Component
@ConfigurationProperties(prefix="person")
public class ConnectionSettings {

    private String firstName;
}

firstName可以使用的属性名如下:

  1. person.firstName,标准的驼峰式命名。
  2. person.first-name,虚线(-)分割方式,推荐在.properties.yml配置文件中使用。
  3. PERSON_FIRST_NAME,大写下划线形式,建议在系统环境变量中使用。

2.5.5 属性验证

可以使用JSR-303注解进行验证,例如:

@Component
@ConfigurationProperties(prefix="connection")
public class ConnectionSettings {

    @NotNull
    private InetAddress remoteAddress;

    // getters and setters ...
}

猜你喜欢

转载自blog.csdn.net/hbtj_1216/article/details/84944378