这一篇主要介绍下SpringBoot配置相关的内容。
通过配置文件,我们可以做到如下事情:
SpringBoot使用全局的配置文件,主配置文件名是固定的: application.xxx
springboot的配置文件有多种格式可选,如:.properties,.xml,.yml。
我个人比较喜欢yaml的简洁,所以推荐使用yaml。
下面介绍些yaml的语法
worker1: name: robin age: 27 worker2: name: jane age: 22
worker1: # a worker object name: robin age: 27
whiteUrl: - www.chobit.org - www.zhyea.com blackUrl: [www.black.com, www.forbidden.com]
worker1: # a worker object name: robin age: 27 worker2: {name: jane, age: 22} # another worker object
content: 'line /n next line'
id: !!int 128 seq: !!str 11112222
worker1: &robin # a worker object name: robin age: 27 worker3: *robin
server: port: 8081 spring: profiles: active: test # 切换配置 --- # 开发环境 spring: profiles: dev --- # 测试环境 spring: profiles: test --- # 生产环境 spring: profiles: prod
如示例代码,在一个yaml文件中存在多个独立区域时,使用 spring.profiles 属性来标识配置区域的profile信息。
在主配置文件application.yml之外,还可以有多个外部配置文件,其名称格式固定为 application-{profile}.yml 。
SpringBoot会根据主配置文件中的 spring.profiles.active 参数来决定加载哪个配置文件。
通过这种方式SpringBoot实现了支持多环境配置,从而能够在不同环境下(开发、测试、生产)进行配置参数的切换。
主配置文件中的 spring.profiles.active 属性还可以有多个值,每个值以逗号进行分割:
spring: profiles: active: dev,test
这种方式允许我们为不同需求创建不同的配置文件。SpringBoot会依序加载每个值指向的配置文件。
配置文件的加载顺序是主配置文件application.yml, spring.profiles.active 指定的外部配置文件。如有冲突项,后面加载的配置会覆盖前面的。
如果多个外部配置文件有相同的配置项,建议在主配置文件中进行配置。
如 spring.profiles.active 指定的值无法与任何外部文件匹配,SpringBoot会尝试加载 application-default.yml 文件。
spring.profiles.active参数不仅可以指明要使用哪个外部配置文件,也可以控制内部实例的选择。这需要通过配合 @ Profile 注解实现。
如下例:
@Profile("prod") @Bean public Worker tom() { return new Worker("Tom", 8); } @Profile("dev") @Bean public Worker jim() { return new Worker("Jim", 8); }
如果没有 @ Profile 注解,在启动的时候SpringBoot就会报错,因为为一个Worker类提供了两个实例。但是现在,SpringBoot可以根据 spring.profiles.active 指明的profile和 @ Profile 注解来选择注入哪个实例。
@ Profile 注解可以用于含有 @ Component 、 @ Configuration 、 @ Bean 等注解的类及其方法。
@ Profile 注解也可以有多个值,如下:
@Profile({"dev", "test"}) @Bean public Worker jim() { return new Worker("Jim", 8); }
这样,在profile是dev或test时,这个Bean都可以被成功注入。
使用SpringBoot的配置项有两种方式:通过 @ Value 注解或通过 @ ConfigurationProperties 注解。这两种方式各有长处,可根据进行选择。
@ Value 注解适用于单个配置项的获取,比如我们可以获取当前的外部配置文件的profile:
@Value("${spring.profiles.active}") private String profile;
@ Value 注解的一个优势是可以使用SPEL表达式(关于SPEL表达式,我有整理过: 《SpringBoot SpEL表达式》 ),如下是一个非常粗略的SPEL表达式:
@Value("#{'token:' + '${custom.token}'}") private String token; //输出结果为:token:zhyeeeeeeee
@ Value 注解的不足之处在于只能获取直接类型的值或字符串,不能映射为复杂类型。
@ PropertiesConfiguration 注解的主要特点是可以将配置映射为对象。因此平时还是通过这种方式获取SpringBoot配置为主。
@ PropertiesConfiguration 注解可应用于类或成员方法。
如下是将应用于类的示例:
@Component @ConfigurationProperties(prefix = "custom") public class CustomConfig { private int id; private String token; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getToken() { return token; } public void setToken(String token) { this.token = token; } }
从示例代码中可以看到配置类需要有 @ Component 注解或 @ Configuration 注解,以便完成注入。
此外,在使用 @ ConfigurationProperties 注解的时候需要传入注入配置属性的前缀,以便获得配置项的范围。
在成员方法上使用 @ PropertiesConfiguration 注解则是一种更为灵活的方式,能够充分弥补 @ Value 注解的不足,示例如下:
@Bean @ConfigurationProperties(prefix = "custom.worker") private Worker getWorker() { return new Worker(); }
注意这里还需要用到 @ Bean 注解,以便将读取到的配置信息注入到实例上。不过不能通过getWorker()方法调用,否则获取的还是一个只有默认值的对象。要使用该实例还是需要通过 @ Autowired 注解来注入。
最后,可以看下我在 GITHUB上的示例应用 ,在里面我尝试了SpringBoot配置的各种应用实践。
就这样。