SpringBoot 项目有一些基本的配置, 比如启动图案 (banner), 比如默认配置文件 application.properties, 以及相关的默认配置项.
示例项目代码在: https://github.com/laolunsi/spring-boot-examples
一, 启动图案 banner
编写 banner.txt 放入 resources 文件夹下, 然后启动项目即可修改默认图案.
关于 banner 的生成, 可以去一些专门的网站.
比如: https://www.bootschool.net/ascii
二, 配置文件 application
2.1 application.properties/YAML
resources 下通常会默认生成一个 application.properties 文件, 这个文件包含了 SpringBoot 项目的全局配置文件. 里面的配置项通常是这样的:
server.port=8080
在这个文件里我们可以添加框架支持的配置项, 比如项目端口号, JDBC 连接的数据源, 日志级别等等.
现在比较流行的是将 properties 文件改为 YAML 文件. YAML 文件的格式 YAML 是这样的:
- server:
- port: 8080
YAML 和 properties 的作用是一样的. 而 YAML 的好处是显而易见的 -- 更易写易读.
属性之间互相调用使用 ${name}:
- eknown:
- email: eknown@163.com
- uri: http://www.eknown.cn
- title: 'hello, link to ${eknown.uri} or email to ${eknown.email}'
链接: SpringBoot 所有官方配置属性
2.2 多环境配置文件
通常开发一个应用会有多个环境, 常见如 dev/prod, 也会有 test, 甚至其他一些自定义的环境, SpringBoot 支持配置文件的灵活切换.
定义新配置文件需要遵循以下格式: application-{profile}.properties 或者 application-{profile}.YAML
比如现在有 dev 和 prod 两个环境, 我需要在 application.YAML 文件之外新建两个文件:
- application-dev.YAML
- server:
- port: 8080
- application-prod.YAML
- server:
- port: 8081
然后在 application.YAML 中通过 application.profiles.active={profile} 指明启用那个配置:
- application:
- profiles:
- active: dev
除了在 application.YAML 中指定配置文件外, 还可以通过启动命令指定: java -jar xxx.jar --spring.profiles.active=dev
2.2 自定义配置项并获取它
主要介绍两种方式, 获取单个配置项和获取多个配置项.
举例:
- eknown:
- email: eknown@163.com
- uri: http://www.eknown.cn
2.2.1 使用 @Value 注解获取单个配置项
- @Value("${eknown.email}")
- private String email;
- @Value("${eknown.uri}")
- private String url;
注意: 使用 @Value 注解的时候, 所在类必须被 Spring 容器管理, 也就是被 @Component,@Controller,@Service 等注解定义的类.
2.2.2 获取多个配置项
第一种, 定义一个 bean 类, 通过 @Value 获取多个配置项:
- @Component
- public class MyConfigBean {
- }
然后我们通过 get 方法来获取这些值:
- @RestController
- public class BasicAction {
- @Autowired
- private MyConfigBean myConfigBean;
- }
第二种, 使用注解 @ConfigurationProperties:
- @Component
- @ConfigurationProperties(perfix="eknown")
- public class MyConfigBean {
- private String email;
- private String uri;
- }
这里只需要通过 prefix 指定前缀即可, 后面的值自动匹配.
这里我们还使用了 @Component 注解来让 spring 容器管理这个 MyConfigBean.
此外, 我们可以不需要引入 @Component, 转而在 Application 启动类上加上 @EnableConfigurationProperties({MyConfigBean.class}) 来启动这个配置.
注意: 我们这里是从主配置文件, 也就是 SpringBoot 默认的 application-profile 文件中获取配置数据的.
而从自定义的配置文件, 比如 test.YAML 这种形式中获取配置项时, 情况是有点不大一样的.
三, 自定义配置文件
上面介绍的配置文件都是 springboot 默认的 application 开头的文件. 如果要自定义一个配置文件呢, 比如 test.YAML 或 test.properties, 怎么获取其中的配置项呢?
使用 @PageResource 注解即可.
首先我们来看一下读取自定义的 properties 文件里的内容:
- test.properties
- hello.time=2019.11.19
- hello.name=eknown
定义 Configuration 类:
- @Configuration
- @PropertySource("classpath:test.properties")
- //@PropertySource("classpath:test.yml") // 注意, YAML 文件不能直接这样写, 会读不出数据
- @ConfigurationProperties(prefix = "hello")
- public class TestConfiguration {
- private String name;
- private String time;
- // hide get and set methods
- }
测试一下:
- @RestController
- @RequestMapping(value = "test")
- public class TestAction {
- @Autowired
- private TestConfiguration testConfiguration;
- @GetMapping(value = "config")
- public String test() {
- return testConfiguration.getName() + "<br/>" + testConfiguration.getTime();
- }
- }
如果将 properties 文件换成 YAML 文件呢?
我们尝试一下, 发现:
读不出数据?
分析一下 @PropertySource 注解, 发现其使用的 PropertySourceFactory 是 DefaultPropertySourceFactory.
这个类的源码如下:
- public class DefaultPropertySourceFactory implements PropertySourceFactory {
- public DefaultPropertySourceFactory() {
- }
- public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
- return name != null ? new ResourcePropertySource(name, resource) : new ResourcePropertySource(resource);
- }
- }
这个类只能处理 properties 文件, 无法处理 YAML 文件. 所以我们需要自定义一个 YmlSourceFactory.
- public class YamlSourceFactory extends DefaultPropertySourceFactory {
- @Override
- public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
- return new YamlPropertySourceLoader().load(resource.getResource().getFilename()
- , resource.getResource()).get(0);
- }
- }
然后定义 test.YAML 文件的 config 类:
- @Configuration
- @PropertySource(value = "classpath:test.yml", encoding = "utf-8", factory = YamlSourceFactory.class)
- @ConfigurationProperties(prefix = "yml.hello")
- public class TestYamlConfiguration {
- private String name;
- private String time;
- // hide get and set methods
- }
注: 为了区分 test.properties 和 test.YAML, 这里的 test.YAML 中的属性以 YAML.hello 开头.
编写一下测试:
- @Autowired
- private TestYamlConfiguration ymlConfiguration;
- @GetMapping(value = "yml")
- public String testYml() {
- return "yml config: <br/>" + ymlConfiguration.getName() + "<br/>" + ymlConfiguration.getTime();
- }
访问:
四, 补充 @ConfigurationProperties
网上一些资料中, 为配合使用 @ConfigurationProperties, 还使用了 @EnableConfigurationProperties 注解.
经过测试发现:
从 SpringBoot 默认配置文件读取配置信息, 使用 @ConfigurationProperties + @Component/@Configuration, 或者 @ConfigurationProperties + 在启动类添加 @EnableConfigurationProperties({class}). 这两种方式都能解决问题
2.1 @PropertySource + @ConfigurationProperties + @Component/@Configuration
2.2 @PropertySource + @ConfigurationProperties + @Component/@Configuration + @EnableConfigurationProperties, 第二种方式存在一个问题, 即还是必须要使用 @Component 注解, 如果不使用, 则会导致读取配置信息为 null, 但程序不会报错; 而如果采用了, 则会导致 bean 类的 set 方法被执行两次 (也就是生成了两个同样类型的 bean 类). 这种方式不建议!
交流学习
个人网站: http://www.eknown.cn/
GitHub: https://github.com/laolunsi
公众号: 猿生物语 ,"分享技术, 也感悟人生", 欢迎关注!
来源: http://www.tuicool.com/articles/VVfY732