![详解Spring Boot:从入门到企业级开发实战](https://wfqqreader-1252317822.image.myqcloud.com/cover/831/47379831/b_47379831.jpg)
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
![](https://epubservercos.yuewen.com/450A7A/26763867809480806/epubprivate/OEBPS/Images/43984_64_1.jpg?sign=1739239242-ZIOGDKrHrmlMRLvn1FlaAcogh9RBprOA-0-d2a424efbe15e66c56583de2911e3311)
(2)编写连接组件。在com.sx.demo包下新建model子包,在model子包下新建ConnectionHelper类,代码如例2-13所示。
例2-13 ConnectionHelper.java
![](https://epubservercos.yuewen.com/450A7A/26763867809480806/epubprivate/OEBPS/Images/43984_64_2.jpg?sign=1739239242-n1DedK7RJb2gEEYptrmz8dFx990SzHWm-0-3d215f00f4f0469e683157c01e5c10bd)
也可以使用@ConfigurationProperties注解将外部属性自动映射到类中的字段上,只要类的属性名称与外部属性的名称相同即可。使用@ConfigurationProperties注解的ConnectionHelper类的代码如下所示:
![](https://epubservercos.yuewen.com/450A7A/26763867809480806/epubprivate/OEBPS/Images/43984_64_3.jpg?sign=1739239242-z0amYZfNZShCXzUk5OHGudjuAkOgMLaa-0-d6c721d31969c299ea8eb4527c7ee6ba)
![](https://epubservercos.yuewen.com/450A7A/26763867809480806/epubprivate/OEBPS/Images/43984_65_1.jpg?sign=1739239242-Faw2FOU3lmaJjzDWbAdaTj75TB0s0nPk-0-2918c6e4d90302dcc00a20e84c8a98b4)
@ConfigurationProperties注解的参数prefix指定要绑定到对象的外部属性的前缀。此外要注意的是,若使用@ConfigurationProperties注解,则类中的字段要提供setter方法。
(3)编写单元测试。在ConnectionHelper类的编辑器窗口中,将光标放到类名上,按下“Alt+Enter”组合键,从弹出的智能辅助列表中选择“Create Test”(如图2-13所示),或者在类名上单击鼠标右键,从弹出菜单中选择【Generate…】→【Test…】。也可以把光标放到类名上,单击菜单【Navigate】→【Test】,在弹出的上下文菜单中,单击【Create New Test…】,调出“Create Test”对话框。
![](https://epubservercos.yuewen.com/450A7A/26763867809480806/epubprivate/OEBPS/Images/43984_65_2.jpg?sign=1739239242-MySBYuNViVvMbTcClPL9d9CyOA1PP7Ev-0-aa1baecc6c9a381d045d64b903a62f44)
图2-13 智能辅助列表
接下来在“Create Test”对话框中,选择要使用的测试库,定义要生成的测试类的名称和位置。我们保持默认选中的JUnit5测试库,测试类的名称和目标包字段的值都保持默认,Create Test对话框如图2-14所示。
单击“OK”按钮,完成测试类的创建,创建的测试类位于src/test/java目录下的com.sx.demo.model包中。
![](https://epubservercos.yuewen.com/450A7A/26763867809480806/epubprivate/OEBPS/Images/43984_66_1.jpg?sign=1739239242-su2Z5qrviy8N39SVPUeFfjLelltvbmFE-0-6511f111f6b98225ad4edc5ee1542eed)
图2-14 Create Test对话框
(4)编写测试方法。打开ConnectionHelperTest类,将光标放到要生成新测试方法的位置上,按下“Alt+Insert”组合键,从弹出的“Generate”快捷菜单中,选择“Test Method”。
也可以在要生成新测试方法的位置上单击鼠标右键,从弹出菜单中选择【Generate】,调出“Generate”快捷菜单。
将生成的测试方法改为合适的名字,编写测试代码,并在ConnectionHelperTest类上使用@SpringBootTest注解,该注解可以加载Spring的上下文,启动Spring容器,自动检索程序的配置文件。
ConnectionHelperTest类的代码如例2-14所示。
例2-14 ConnectionHelperTest.java
![](https://epubservercos.yuewen.com/450A7A/26763867809480806/epubprivate/OEBPS/Images/43984_66_2.jpg?sign=1739239242-Cds8egVxjkoyOxBuRUlFmg26Uq1xXt7G-0-0145aed4dfdd265bdda6766f9068886f)
代码中使用了@Autowired注解,自动注入ConnectionHelper类的实例。
(5)执行测试。将光标放到test()方法上,单击鼠标右键,从弹出的菜单中选择【Run'test()'】,程序输出结果为:
![](https://epubservercos.yuewen.com/450A7A/26763867809480806/epubprivate/OEBPS/Images/43984_66_3.jpg?sign=1739239242-7mIweyp0oaZFKNCziuBydAAjxwTZYYMs-0-d67dc3c139f8f9c89749e9ac549a8ab5)
(6)配置环境变量,覆盖jdbc.username和jdbc.password属性的值。将光标放到test()方法上,单击鼠标右键,从弹出的菜单中选择【More Run/Debug】→【Modify Run Configuration…】,然后在“Edit Run Configuration”对话框的环境变量一栏中输入jdbc.username=lisi;jdbc.password=5678,如图2-15所示。
![](https://epubservercos.yuewen.com/450A7A/26763867809480806/epubprivate/OEBPS/Images/43984_67_1.jpg?sign=1739239242-J0E2hfCN9hBqqanuNt61IHfwfKi9XrTQ-0-831a8f63e3a32c23a44034992c5227b8)
图2-15 配置环境变量
在环境变量配置完毕后,再次运行test()方法,结果如下所示:
![](https://epubservercos.yuewen.com/450A7A/26763867809480806/epubprivate/OEBPS/Images/43984_67_2.jpg?sign=1739239242-odwnhTap4rlYY6dMPcJ5eaIUVkDcCNM4-0-754f3acbc6be8c3a30742e836998759c)
因为环境变量的优先级要高于配置文件,所以配置文件中同名属性的值会被覆盖。