spring boot 加载配置

2021-08-27 17:40:09

spring boot 框架的初衷是自动化配置,将一坨坨的配置文件收进了抽屉里,让你的项目看起来简洁清爽了起来。但是这些配置并没有消失,而是收纳进了框架内部。项目定制化的配置可以无中生有的装配到项目中,在容器中可以直接使用。加载配置有多种方式,做一个记录。
spring boot 默认会从 src/main/resourcessrc/main/resources/config 路径中加载 application.properties、application.yml 配置文件,作为默认配置。

一、单项配置

使用 @Value 注解,在容器范围内的任一变量上,可以直接加载一个配置到该变量。 @Value 注解在 Bean 加载之后自动执行。

简单使用

例如在配置文件application.properties中写如下一个配置项

#application.properties
port=9000

在本个配置类中加载该配置

//AppServiceConfig.java

@Configuration
@Data
public class AppServiceConfig {
    @Value("${port}")
    private Integer port;
}

在主类中查看这个配置

// ConfigrApplication.java

@SpringBootApplication
public class ConfigrApplication implements CommandLineRunner {
    @Autowired
    private AppServiceConfig config;

    public static void main(String[] args) {
        SpringApplication.run(NettyServerApplication.class, args);

    }

    @Override
    public void run(String... args) throws Exception {
        System.out.println(config);
    }
}

使用路径

在配置文件中修改配置项目为:port=9000,在配置类中修改为 @Value("${app.port}") ,执行程序查看结果,仍然正确加载了配置。

默认值

如果在加载代码中加载了一个不存在的配置,可以指定一个默认值,例如 @Value("${app.port:9000}") ,同时在配置文件中删掉 port 配置项,启动系统会看到 port 已经配置成了默认值。

二、对象配置

每次配置一个配置项在有些复杂配置中不够简洁,是否可以指定一个规则自动的配置出一个对象的所有属性呢,答案当然是可以。
使用 @ConfigurationProperties 注解在配置对象上,可以自动的同名属性配置化。

基本对象

#application.properties

app.port=9000
app.timeout=120
app.node=master

在本个配置类中加载该配置

//AppServiceConfig.java

@Configuration
@ConfigurationProperties(prefix = "app")
@Data
public class AppServiceConfig {
    private Integer port;
    private Integer timeout;
    private String node;

    @PostConstruct
    public void PostConstruct(){
        System.out.println("@PostConstruct");
        System.out.println(this);
    }
}

复杂对象

可以直接装配 Map、List等类型的对象,示例如下:

#application.properties

app.port=9000
app.timeout=120
app.node=master

#map
app.map[k1]=v1
app.map[k2]=v2

#list
app.list[0]=l1
app.list[1]=l2

在本个配置类中加载该配置

//AppServiceConfig.java

@Configuration
@ConfigurationProperties(prefix = "app")
@Data
public class AppServiceConfig {
    private Integer port;
    private Integer timeout;
    private String node;

    private Map<String, String> map;

    private List<String> list;

    @PostConstruct
    public void PostConstruct(){
        System.out.println("@PostConstruct");
        System.out.println(this);
    }
}

可以看到已经加载了复杂对象。

三、路径配置

默认的配置项都在主配置文件 (application.properties、application.yml) 中,为了更清晰的分离配置,可以通过 @PropertySource 注解指定配置文件。该注解可以和前两项注解组合使用。
假设将配置项单独放置在 app.properties文件中。

类路径

@PropertySource("classpath:app.properties")

使用类路径有一定的加载顺序,一般代码内部包含了这个文件,在外面有同名文件也不会覆盖配置,需要额外注意。

绝对路径

@PropertySource("file:app.properties")

如果在外部配置该文件,推荐用这种方式。

配置列表

在主配置文件中通过 spring.profiles.include 参数,指定额外的配置文件,与 @PropertySource 注解起到类似的效果,但是更加灵活。但是对于配置文件名需要符合 application-xx.properties 的格式,例如本实例,将 app.properties改名为 application-app.properties
在主配置文件中进行配置:

# application.properties

spring.profiles.include=app

在目标配置中写入配置项

# application-app.properties

app.port=9000
app.timeout=120
app.node=master

#map
app.map[k1]=v1
app.map[k2]=v2

#list
app.list[0]=l1
app.list[1]=l2

加载配置类

//AppServiceConfig.java

@Configuration
@ConfigurationProperties(prefix = "app")
@Data
public class AppServiceConfig {
    private Integer port;
    private Integer timeout;
    private String node;

    private Map<String, String> map;

    private List<String> list;

    @PostConstruct
    public void PostConstruct(){
        System.out.println("@PostConstruct");
        System.out.println(this);
    }
}
Copyright tg-blog 京ICP备15066502号-2