Profile使用的示例分析
在项目开发中,很多配置它在开发环境和线上环境是不一样的,最为典型就是数据库连接、redis连接等。
一般来说,最次都会有两种环境(公司越大、项目越复杂,环境会越多~):
- 开发环境dev
- 生产环境prod
本文就以这两个环境为基础,用一个非常简单的例子来演示profile的使用:
@Configuration public class RootConfig { @Profile({"default"}) // 显示的指出defualt~~~ @Bean("person") public Person personDefault() { return new Person("我代表defualt数据源", 0); } @Profile({"dev", "test"}) @Bean("person") public Person personDev() { return new Person("我代表dev数据源", 66); } @Profile({"prod", "online"}) @Bean("person") public Person personProd() { return new Person("我代表prod数据源", 88); } }
验证:
public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(RootConfig.class); Environment environment = context.getEnvironment(); String[] activeProfiles = environment.getActiveProfiles(); String[] defaultProfiles = environment.getDefaultProfiles(); System.out.println(ArrayUtils.toString(activeProfiles)); //{} System.out.println(ArrayUtils.toString(defaultProfiles)); //{default} System.out.println(context.getBean("person")); }
结果打印:
{} {default} Person{name='我代表defualt数据源', age=0}
由于我没有手动设置过任何激活Profiles,所以走默认的,因此最终被放进容器的Person对象就是我们那个@Profile({"default"})
默认的。
手动设置激活的Profiles:
public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); // 手动设置激活的Profiles ConfigurableEnvironment environment = context.getEnvironment(); environment.setActiveProfiles("dev", "test1", "test2"); // environment.setDefaultProfiles("",""); // 也可以设置默认的 只是一般都不这么干~ context.register(RootConfig.class); context.refresh(); String[] activeProfiles = environment.getActiveProfiles(); String[] defaultProfiles = environment.getDefaultProfiles(); System.out.println(ArrayUtils.toString(activeProfiles)); //{} System.out.println(ArrayUtils.toString(defaultProfiles)); //{default} System.out.println(context.getBean("person")); }
结果打印:
{dev,test1,test2} {default} Person{name='我代表dev数据源', age=66}
结果符合我们预期。这里需要注意的是:environment.setActiveProfiles()方法必须在容器启动之前调用,否则无效。
(激活prod的做法一样,此处就无需再演示了~~~)
Tips:若类/方法上没有标注任何@Profile注解的,不受到activeProfiles的影响,都会被加入到容器。
激活profile的6种方式
上面示例介绍的是自己手动API调用方式去激活profile,但在实际开发中,这样做显得非常的麻烦,而且并不是每位小伙伴都知道这个API和调用时机,使用门槛偏高。
Spring考虑到了这一点,所以它提供了非常多的方式让你可以激活profile,任君灵活选择。本文我介绍如下6种方式:
方式一:API调用方式
见上例
方式二:properties配置文件方式
写一个属性文件:profile.properties
spring.profiles.active = prod
把资源文件导入进容器,然后启动即可
@PropertySource("classpath:profile.properties") @Configuration public class RootConfig { ... } public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(RootConfig.class); Environment environment = context.getEnvironment(); String[] activeProfiles = environment.getActiveProfiles(); String[] defaultProfiles = environment.getDefaultProfiles(); System.out.println(ArrayUtils.toString(activeProfiles)); //{} System.out.println(ArrayUtils.toString(defaultProfiles)); //{default} System.out.println(context.getBean("person")); }
结果输出:
{prod} {default} Person{name='我代表prod数据源', age=88}
注意:下面集中方式是SpringBoot环境下可直接使用的方式(Spring环境下默认不支持):
方式三:多profile文件方式
类似这么来写:
- application-dev.properties
- application-prod.properties
当然:类似的写多个yml也是可以的,此处就不作为一种新方式了
方式四:yml文件多文档块方式
略
方式五:命令行参数方式(重要)
形如:
方式六:JVM参数方式
形如:
思考题:若上面6中方式都有(SpringBoot环境下),或者只配置某几种方式,它们的优先级、最终谁会生效你知道吗?
这个问题各位小伙伴可自行思考,此处我给出两点提示:
- API调用方式的优先第一考虑
- 各式各样的PropertySource属性源的优先级才是应该考虑的重中之重
总结
本篇文章讲述的内容还是非常非常简单的,核心是Environment它来管理profile。@Profile使用简单但功能强大,熟练的使用它很多时候都能让你达到事半功倍的效果。
了解了Environment以及PropertySource的联系以及编程模式,可以极大的实现程序的弹性。比如你可以抛弃Spring Cloud Config配置,自己采用第三方的集成
最努力、最勤奋的人往往不是输出"最多"的,因为在人口众多且效率为王的当下,只有越特殊越稀缺的人才,才越会被受到重视。