profile之springboot
文章目录
什么是profile
想必大家都有这种经历,我们开发项目的时候要有多个环境,如开发环境、测试环境、生产环境,他们的配置文件一般不同,如数据库地址。当我们要向各个环境发布程序时,需要人工处理这些配置文件,这显然麻烦且易错。有了profile,一切问题就简单了。简单讲profile就是一组配置,不同profile提供不同组合的配置,程序运行时可以选择使用哪些profile来适应环境。
1. application-{profile}.properties文件
我们先来搭建一个简单的springboot项目快速了解多profile的使用。项目结构非常简单:
除了application.properties还有多个application-{profile}.properties(格式必须为这样),在每个配置文件中项目启动的端口是不一样的。
在application.properties使用spring.profiles.active=prod来指定生效的配置文件为application-prod.properties.启动项目后可以在控制台看到启动端口为application-prod.properties里配置的server.port=8084
1.1 profile的多种激活方式
- 第一种就是上面的在配置文件中通过spring.profiles.active=来指定,注意可以激活多个profile,如spring.profiles.active=prod,dev,如果都存在某值,执行last win策略。
- 通过命令行方式。优先级高于第一种的spring.profiles.active
执行java -jar xxx.jar,可以观察到服务端口被设置为8082。
执行java -jar xxx.jar –spring.profiles.active=test,可以观察到服务端口被设置为8083,也就是(test)环境的配置
- 通过虚拟机参数。-Dspring.profiles.active=dev
- 使用编程的方式激活。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args);
applicationContext.getEnvironment().setActiveProfiles("dev");
}
}
1.2 spring.profiles.include属性
意思是无论执行哪个profile,都会去加载application-mq.properties里的配置。但是注意,只会去加载application-mq.properties里独有的配置,如果application-mq.properties也有server.port字段并不会生效。
可以利用这种方式简化配置文件的书写,如在application-mq.properties书写各个环境都有的mq配置信息,不必都夹杂在application.properties里。
1.3 总结
- application.properties文件是必定要加载的,而且是先加载的,无论是通过哪种方式指定的。
- 当加载完application文件之后才加载指定的profiles文件
- 如果application文件和指定的profile文件有相同的配置或冲突的配置项,则以profile中的为基准
- application文件中写通用的配置项,profile文件中写特定环境的配置项,spring.profiles.include指定公共的配置项(起到了分离的作用),这样可以简化配置文件的书写。
2. @Profile
通过@Profile注解,我们可以根据所激活的不同的环境,生成不同的bean。
如只在dev环境下启动swagger2:
/**
* swagger2的配置,只在开发环境dev下存在
*/
@Configuration
@EnableSwagger2
@Profile("dev")
public class Swagger2Config {
}
2.1 注解可以使用的位置
- @component或@Configuration修饰的类上
- 作为元注解修饰自定义注解
- 任何@Bean修饰的方法上
2.2 自定义注解
@Profile注解需要接受一个字符串,作为场景名。这样每个地方都需要记住这个字符串。Spring的@Profile注解支持定义在其他注解之上,以创建自定义场景注解。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Profile("dev")
public @interface Dev{
}
这样就创建了一个@Dev注解,该注解可以标识bean使用于@Dev这个场景。后续就不再需要使用@Profile(“dev”)的方式(这样即可以简化代码)。
2.3 注意
- @Profile({“p1”, “!p2”})的意思为p1的profile生效或p2的profile为生效时就会去生成修饰的类
- 如果要使用不同环境下生成不同配置的同一个bean,方法名不要相同,即尽量不要重载。
3. 和maven的profile一起使用
参看这篇博客结合maven的profile使用