2.5 外部配置
Spring Boot允许将配置外部化,以便在不同的环境中使用相同的应用程序代码。可以使用各种外部配置源,包括Java属性文件、YAML文件、环境变量和命令行参数。
属性值可以通过@Value注解直接注入Bean中,通过Spring的Environment抽象访问,或者通过@ConfigurationProperties绑定到结构化对象。
Spring Boot使用了一个非常特殊的PropertySource顺序,旨在允许合理地覆盖值,属性按以下顺序覆盖值(靠后的项的值将覆盖靠前的项的值)。
(1)默认属性(通过设置SpringApplication.setDefaultProperties指定)。
(2)@Configuration类上的@PropertySource注解。要注意的是,在刷新应用程序上下文之前,不会将此类属性源添加到Environment中。
(3)配置数据(如application.properties文件)。
(4)RandomValuePropertySource,它只在random.*中具有属性。
(5)操作系统环境变量。
(6)Java系统属性(System.getProperties())。
(7)来自java:comp/env的JNDI属性。
(8)ServletContext初始化参数。
(9)ServletConfig初始化参数。
(10)来自SPRING_APPLICATION_JSON的属性(嵌入在环境变量或系统属性中的内联JSON)。
(11)命令行参数。
(12)在测试上的properties属性。该属性在@SpringBootTest注解上可用,以及测试应用程序特定部分的测试注解上可用。
(13)测试上的@TestPropertySource注解。
(14)在devtools处于活动状态时,$HOME/.config/spring-boot目录中的devtools全局设置属性。
下面看一个示例。我们将JDBC连接数据库所需要的信息放到配置文件中,然后在连接组件中通过@Value注解获取配置文件中的信息,之后在外部配置中修改JDBC连接信息。
(1)先在application.yml中添加一些配置信息,为了简单起见,只给出JDBC连接所需要的用户名和密码,代码如例2-12所示。
例2-12 application.yml
(2)编写连接组件。在com.sx.demo包下新建model子包,在model子包下新建ConnectionHelper类,代码如例2-13所示。
例2-13 ConnectionHelper.java
也可以使用@ConfigurationProperties注解将外部属性自动映射到类中的字段上,只要类的属性名称与外部属性的名称相同即可。使用@ConfigurationProperties注解的ConnectionHelper类的代码如下所示:
@ConfigurationProperties注解的参数prefix指定要绑定到对象的外部属性的前缀。此外要注意的是,若使用@ConfigurationProperties注解,则类中的字段要提供setter方法。
(3)编写单元测试。在ConnectionHelper类的编辑器窗口中,将光标放到类名上,按下“Alt+Enter”组合键,从弹出的智能辅助列表中选择“Create Test”(如图2-13所示),或者在类名上单击鼠标右键,从弹出菜单中选择【Generate…】→【Test…】。也可以把光标放到类名上,单击菜单【Navigate】→【Test】,在弹出的上下文菜单中,单击【Create New Test…】,调出“Create Test”对话框。
图2-13 智能辅助列表
接下来在“Create Test”对话框中,选择要使用的测试库,定义要生成的测试类的名称和位置。我们保持默认选中的JUnit5测试库,测试类的名称和目标包字段的值都保持默认,Create Test对话框如图2-14所示。
单击“OK”按钮,完成测试类的创建,创建的测试类位于src/test/java目录下的com.sx.demo.model包中。
图2-14 Create Test对话框
(4)编写测试方法。打开ConnectionHelperTest类,将光标放到要生成新测试方法的位置上,按下“Alt+Insert”组合键,从弹出的“Generate”快捷菜单中,选择“Test Method”。
也可以在要生成新测试方法的位置上单击鼠标右键,从弹出菜单中选择【Generate】,调出“Generate”快捷菜单。
将生成的测试方法改为合适的名字,编写测试代码,并在ConnectionHelperTest类上使用@SpringBootTest注解,该注解可以加载Spring的上下文,启动Spring容器,自动检索程序的配置文件。
ConnectionHelperTest类的代码如例2-14所示。
例2-14 ConnectionHelperTest.java
代码中使用了@Autowired注解,自动注入ConnectionHelper类的实例。
(5)执行测试。将光标放到test()方法上,单击鼠标右键,从弹出的菜单中选择【Run'test()'】,程序输出结果为:
(6)配置环境变量,覆盖jdbc.username和jdbc.password属性的值。将光标放到test()方法上,单击鼠标右键,从弹出的菜单中选择【More Run/Debug】→【Modify Run Configuration…】,然后在“Edit Run Configuration”对话框的环境变量一栏中输入jdbc.username=lisi;jdbc.password=5678,如图2-15所示。
图2-15 配置环境变量
在环境变量配置完毕后,再次运行test()方法,结果如下所示:
因为环境变量的优先级要高于配置文件,所以配置文件中同名属性的值会被覆盖。