springboot(十)--多环境profile的使用

如题,本篇我们介绍在springboot中多环境profile的使用。

在我们的项目开发、测试、上线过程中,不可避免的需要反复地修改配置文件。譬如,开发环境连接的数据库ip和测试、生产环境的不同;开发环境开发的app版本和测试、生产线上的app版本信息也不同,等等。。我们发现,尽管在springboot中使用application.properties (或者yml)作为整个项目的全局配置文件,但是生产、测试环境往往都会有些不同于开发环境的配置,这时候profile就派上用场了。

 

另外 ,使用profile还有个明显的用处——可以抽取application.yml中的配置信息到其他文件。

如当我们的项目越来越大时,项目配置信息太多,application.yml配置文件会比较大,这时我们可以通过定义profile,将一些配置信息从application.yml中抽取到一个单独的文件中,如建立:

application-devFtp.yml   只存放开发环境ftp相关的配置信息

application-devRedis.yml   只存放开发环境redis相关的配置信息

application-testFtp.yml   只存放测试环境ftp相关的配置信息

application-testRedis.yml   只存放测试环境redis相关的配置信息

 

然后在application.yml中 ,切换开发环境,配置spring.profiles.active=dev, devFtp,devRedis 来引入dev、devFtp、devRedis的配置即可。切换测试环境,配置spring.profiles.active=test, testFtp,testRedis 来引入test、testFtp、testRedis的配置 即可。

 

注意:properties的配置文件含中文时读取会乱码,而在yml中不会,因此建议大家使用yml配置文件替换properties配置文件

 

一、application.properties和application-{profile}.properties配置

profile允许在项目中同时配置多套与环境相关的配置,profile的文件名称为application-{profile}.properties(以properties文件为例),其中profile可以为dev(开发)、test(测试)、prod(生产)等,这些名称是用户自定义的。当需要切换到指定环境配置时,只需将application.properties中spring.profiles.active设置为指定的profile名称即可。 如:

application.properties

# profile 配置 dev test prod
spring.profiles.active=dev
#spring.profiles.active=test
#spring.profiles.active=prod

application-dev.properties

app.myname=dev_app

application-test.properties

app.myname=test_app

application-prod.properties

 app.myname=prod_app

SpringContextEventHandler.java 中使用@Value("${app.myname}")注入值,并打印之

package com.tingcream.springWeb.spring.eventListener;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.ContextStartedEvent;
import org.springframework.context.event.ContextStoppedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
 
import com.tingcream.springWeb.common.SpringContextHelper;
import com.tingcream.springWeb.spring.event.MyAppEvent;
 
 
@Component
public class SpringContextEventHandler {
     
     @Value("${app.myname}")
     private String myname;
   
     @EventListener
     public void stopped(ContextStoppedEvent event){
       System.out.println("SpringContextEventHandler stopped执行");
     }
      
     @EventListener
     public void started(ContextStartedEvent event){
         System.out.println("SpringContextEventHandler started执行");
     }
      
     @EventListener
     public void refreshed(ContextRefreshedEvent event){
         System.out.println("SpringContextEventHandler refreshed执行");
         System.out.println("myname:"+myname);//打印@value注入的值
          SpringContextHelper.getApplicationContext().publishEvent(new MyAppEvent("这是一段事件消息"));
          
     }
     @EventListener
     public void closed(ContextClosedEvent event){
         System.out.println("SpringContextEventHandler closed执行");
     }
      
     // ready
     @EventListener
     public void ready(ApplicationReadyEvent  event){
         System.out.println("SpringContextEventHandler ready执行..");
     }
 
}

当我们修改application.properties中spring.profiles.active为不同值时,@Value("${app.myname}")所注入的值也不同。 

二、使用@Profile("xxx")指定bean在特定的profile环境中创建

@Profile注解可以标记在任何被标记了@Configuration或@Component的java配置类声明或方法声明上。

如,我们开发环境、测试环境、生产环境中的android app版本信息不同,可以配置3个bean,分别指定不同的profile 。 

 

AndroidAppConfiguration.java

package com.tingcream.springWeb.configuration;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
 
import com.tingcream.springWeb.model.AndroidApp;
 
 
/**
 * android app版本 对象配置
 * @author jelly
 *
 */
@Configuration
public class AndroidAppConfiguration {
     
     
    @Bean
    @Profile("dev")
    public AndroidApp  devAndroidApp(){
        System.out.println("dev androidApp对象创建");
        return  new AndroidApp("我的e家掌上app", "v2.1.0", "2012-09-20", "开发环境,app描述信息");
    }
    @Bean
    @Profile("test")
    public AndroidApp  testAndroidApp(){
        System.out.println("test androidApp对象创建");
        return  new AndroidApp("我的e家掌上app", "v2.0.0", "2012-09-20", "测试环境,app描述信息");
         
    }
    @Bean
    @Profile("prod")
    public AndroidApp  prodAndroidApp(){
        System.out.println("prod androidApp对象创建");
        return  new AndroidApp("我的e家掌上app", "v1.5.0", "2012-09-20", "生产环境,app描述信息");
    }
 
}

AndroidApp.java

package com.tingcream.springWeb.model;
 
public class AndroidApp {
     
    private String name;
    private String version;
    private String publishDate;
    private String describe;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getVersion() {
        return version;
    }
    public void setVersion(String version) {
        this.version = version;
    }
    public String getPublishDate() {
        return publishDate;
    }
    public void setPublishDate(String publishDate) {
        this.publishDate = publishDate;
    }
    public String getDescribe() {
        return describe;
    }
    public void setDescribe(String describe) {
        this.describe = describe;
    }
    public AndroidApp() {
        super();
          
    }
    public AndroidApp(String name, String version, String publishDate,
            String describe) {
        super();
        this.name = name;
        this.version = version;
        this.publishDate = publishDate;
        this.describe = describe;
    }
    @Override
    public String toString() {
        return "AndroidApp [name=" + name + ", version=" + version
                + ", publishDate=" + publishDate + ", describe=" + describe
                + "]";
    }
 
}

SpringContextEventHandler.java 

package com.tingcream.springWeb.spring.eventListener;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.ContextStartedEvent;
import org.springframework.context.event.ContextStoppedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
 
import com.tingcream.springWeb.common.SpringContextHelper;
import com.tingcream.springWeb.model.AndroidApp;
import com.tingcream.springWeb.spring.event.MyAppEvent;
 
 
@Component
public class SpringContextEventHandler {
     
     @Value("${app.myname}")
     private String myname;
     
      
     @Autowired
     private AndroidApp androidApp;//注入androidApp版本对象
      
     @EventListener
     public void stopped(ContextStoppedEvent event){
       System.out.println("SpringContextEventHandler stopped执行");
     }
      
     @EventListener
     public void started(ContextStartedEvent event){
         System.out.println("SpringContextEventHandler started执行");
     }
      
     @EventListener
     public void refreshed(ContextRefreshedEvent event){
         System.out.println("SpringContextEventHandler refreshed执行");
         System.out.println("myname:"+myname);//打印@value注入的值
          
         System.out.println(androidApp);//打印注入的android对象,根据指定的profile不同(dev、test、prod)打印的内容也不同
          
         SpringContextHelper.getApplicationContext().publishEvent(new MyAppEvent("这是一段事件消息"));
          
     }
     @EventListener
     public void closed(ContextClosedEvent event){
         System.out.println("SpringContextEventHandler closed执行");
     }
      
     // ready
     @EventListener
     public void ready(ApplicationReadyEvent  event){
         System.out.println("SpringContextEventHandler ready执行..");
     }
 
}

当我们修改application.properties配置文件中spring.profiles.active的值为不同值时,容器中使用@Autowire 注入的AndroidApp对象也不同。

---------

当然,@Profile 注解也可以标记在类上,如我们在代码中配置三个环境特有的配置:DevConfiguration、TestConfiguration、ProdConfiguration

DevConfiguration.java

package com.tingcream.springWeb.configuration;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
 
import com.tingcream.springWeb.model.AndroidApp;
 
/**
 * dev profile 特有配置
 * @author jelly
 *
 */
@Configuration
@Profile("dev")
public class DevConfiguration {
     
    @Bean
    public AndroidApp androidApp(){
        System.out.println("dev androidApp对象创建");
        return  new AndroidApp("我的e家掌上app", "v2.1.0", "2012-09-20", "开发环境,app描述信息");
          
    }
  
}

TestConfiguration.java

package com.tingcream.springWeb.configuration;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
 
import com.tingcream.springWeb.model.AndroidApp;
/**
 * test profile 特有配置
 * @author jelly
 *
 */
@Configuration
@Profile("test")
public class TestConfiguration {
 
     
    @Bean
    public AndroidApp androidApp(){
        System.out.println("test androidApp对象创建");
        return  new AndroidApp("我的e家掌上app", "v2.0.0", "2012-09-20", "测试环境,app描述信息");
          
    }
}

ProdConfiguration.java

package com.tingcream.springWeb.configuration;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
 
import com.tingcream.springWeb.model.AndroidApp;
 
/**
 * prod profile 特有配置
 * @author jelly
 *
 */
@Configuration
@Profile("prod")
public class ProductionConfiguration {
     
    @Bean
    public AndroidApp androidApp(){
        System.out.println("prod androidApp对象创建");
        return  new AndroidApp("我的e家掌上app", "v1.5.0", "2012-09-20", "生产环境,app描述信息");
          
    }
 
}

--------

除了在配置文件可指定激活哪个profile,我们也可以通过VM参数或程序参数在程序运行时手动指定, 如:

配置文件 spring.profiles.active=test

VM 参数 -Dspring.profiles.active=test
程序参数  --spring.profiles.active=test

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值