很多时候, 我们项目在开发环境和生成环境的环境配置是不一样的, 例如, 数据库配置, 在开发的时候, 我们一般用测试数据库, 而在生产环境的时候, 我们是用正式的数据, 这时候, 我们可以利用 profile 在不同的环境下配置用不同的配置文件或者不同的配置
spring boot 允许你通过命名约定按照一定的格式 (application-{profile}.properties) 来定义多个配置文件, 然后通过在 application.properyies 通过 spring.profiles.active 来具体激活一个或者多个配置文件, 如果没有没有指定任何 profile 的配置文件的话, spring boot 默认会启动 application-default.properties.
profile 的配置文件可以按照 application.properyies 的放置位置一样, 放于以下四个位置,
当前目录的 "/config" 的子目录下
当前目录下
classpath 根目录的 "/config" 包下
classpath 的根目录下
在这里我们就定义俩个 profile 文件, application-cus1.properties 和 application-cus2.properties, 并在俩个文件中都分别写上变量 cusvar=cus1 和 cusvar=cus2
我们在 application.properyies 也写上, 并把 profile 切换到 application-cus1.properties 的配置文件
复制
- cusvar=cus3
- spring.profiles.active=cus1
可以通过这样子来测试
复制
- @RestController
- @RequestMapping("/task")
- public class TaskController {
- @RequestMapping(value = {"/",""})
- public String hellTask(@Value("${cusvar}")String cusvar ){
- return "hello task !! myage is" + cusvar;
- }
- }
在这里可以看到 spring.profiles.active 激活的 profile 不同, 打印出来的结果也不一样.
除了可以用 profile 的配置文件来分区配置我们的环境变量, 在代码里, 我们还可以直接用 @Profile 注解来进行配置, 例如数据库配置, 这里我们先定义一个接口
复制
- public interface DBConnector {
- public void configure();
- }
分别定义俩个实现类来实现它
复制
- /**
- * 测试数据库
- */
- @Component
- @Profile("testdb")
- public class TestDBConnector implements DBConnector {
- @Override
- public void configure() {
- System.out.println("testdb");
- }
- }
- /**
- * 生产数据库
- */
- @Component
- @Profile("devdb")
- public class DevDBConnector implements DBConnector {
- @Override
- public void configure() {
- System.out.println("devdb");
- }
- }
通过在配置文件激活具体使用哪个实现类
复制
spring.profiles.active=testdb
然后就可以这么用了
复制
- @RestController
- @RequestMapping("/task")
- public class TaskController {
- @Autowired DBConnector connector ;
- @RequestMapping(value = {"/",""})
- public String hellTask(){
- connector.configure(); // 最终打印 testdb
- return "hello task !! myage is" + myage;
- }
- }
除了 spring.profiles.active 来激活一个或者多个 profile 之外, 还可以用 spring.profiles.include 来叠加 profile
复制
- spring.profiles: testdb
- spring.profiles.include: proddb,prodmq
以上就是 spring boot 用 profile 的作用
通过命令行设置属性值
相信使用过一段时间 Spring Boot 的用户, 一定知道这条命令: java -jar xxx.jar --server.port=8888, 通过使用 --server.port 属性来设置 xxx.jar 应用的端口为 8888.
在命令行运行时, 连续的两个减号 -- 就是对 application.properties 中的属性值进行赋值的标识. 所以, java -jar xxx.jar --server.port=8888 命令, 等价于我们在 application.properties 中添加属性 server.port=8888, 该设置在样例工程中可见, 读者可通过删除该值或使用命令行来设置该值来验证.
通过命令行来修改属性值固然提供了不错的便利性, 但是通过命令行就能更改应用运行的参数, 那岂不是很不安全? 是的, 所以 Spring Boot 也贴心的提供了屏蔽命令行访问属性的设置, 只需要这句设置就能屏蔽: SpringApplication.setAddCommandLineProperties(false).
多环境配置
以上都不是重点, 这才是重点, 这才是重点, 这才是重点, 重要的事情说 3 遍. 我们在开发 Spring Boot 应用时, 通常同一套程序会被应用和安装到几个不同的环境, 比如: 开发, 测试, 生产等. 其中每个环境的数据库地址, 服务器端口等等配置都会不同, 如果在为不同环境打包时都要频繁修改配置文件的话, 那必将是个非常繁琐且容易发生错误的事.
对于多环境的配置, 各种项目构建工具或是框架的基本思路是一致的, 通过配置多份不同环境的配置文件, 再通过打包命令指定需要打包的内容之后进行区分打包, Spring Boot 也不例外, 或者说更加简单.
在 Spring Boot 中多环境配置文件名需要满足 application-{profile}.properties 的格式, 其中 {profile} 对应你的环境标识, 比如:
application-dev.properties: 开发环境
application-test.properties: 测试环境
application-prod.properties: 生产环境
至于哪个具体的配置文件会被加载, 需要在 application.properties 文件中通过 spring.profiles.active 属性来设置, 其值对应 {profile} 值.
如: spring.profiles.active=test 就会加载 application-test.properties 配置文件内容
下面, 以不同环境配置不同的服务端口为例, 进行样例实验.
针对各环境新建不同的配置文件 application-dev.properties,application-test.properties,application-prod.properties
在这三个文件均都设置不同的 server.port 属性, 如: dev 环境设置为 8080,test 环境设置为 9090,prod 环境设置为 80
application.properties 中设置 spring.profiles.active=dev, 就是说默认以 dev 环境设置
测试不同配置的加载:
执行 java -jar xxx.jar, 可以观察到服务端口被设置为 8080, 也就是默认的开发环境(dev)
执行 java -jar xxx.jar --spring.profiles.active=test, 可以观察到服务端口被设置为 9090, 也就是测试环境的配置(test)
执行 java -jar xxx.jar --spring.profiles.active=prod, 可以观察到服务端口被设置为 80, 也就是生产环境的配置(prod)
按照上面的实验, 可以如下总结多环境的配置思路:
application.properties 中配置通用内容, 并设置 spring.profiles.active=dev, 以开发环境为默认配置
application-{profile}.properties 中配置各个环境不同的内容
通过命令行方式去激活不同环境的配置.
多环境高级应用
在某些情况下, 应用的某些业务逻辑可能需要有不同的实现. 例如邮件服务, 假设 EmailService 中包含的 send(String email)方法向指定地址发送电子邮件, 但是我们仅仅希望在生产环境中才执行真正发送邮件的代码, 而开发环境里则不发送以免向用户发送无意义的垃圾邮件.
我们可以借助 Spring 的注解 @Profile 实现这样的功能, 这样需要定义两个实现 EmailService 借口的类:
复制
- /**
- * 发送邮件接口.
- */
- public interface EmailService {
- /** 发送邮件 */
- publicvoid send();
- }
发送邮件的具体实现(dev - 开发环境的代码):
- @Service
- @Profile("dev") // 开发环境的时候.
- public class DevEmailServiceImpl implements EmailService{
- @Override
- publicvoid send() {
- System.out.println("DevEmailServiceImpl.send(). 开发环境不执行邮件的发送.");
- }
- }
发送邮件的具体实现(prod - 生产环境的代码):
复制
- @Service
- @Profile("prod") // 生产环境.
- public class ProdEmailServiceImpl2 implements EmailService{
- @Override
- publicvoid send() {
- System.out.println("DevEmailServiceImpl.send(). 生产环境执行邮件的发送.");
- // 具体的邮件发送代码.
- //mail.send();
- }
- }
@Profile("dev")表明只有 Spring 定义的 Profile 为 dev 时才会实例化 DevEmailService 这个类. 那么如何设置 Profile 呢?
在配置文件中指定
在 application.properties 中加入:
复制
spring.profiles.active=dev
通过命令行参数
复制
java -jar App.jar --spring.profiles.active=dev
来源: https://www.cnblogs.com/xinglongbing521/p/10275291.html