博客详情

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

作者: 朝如青丝暮成雪
发布时间:2018-08-15 16:20:53  文章分类:springboot   阅读(842)  评论(0)

如题,本篇我们介绍在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的配置文件中含中文,spring的属性文件加载后读取乱码,而在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参数或程序参数在程序运行时手动指定profile, 如:

配置文件 spring.profiles.active=test

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



关键字:  springboot  profile
评论信息
暂无评论
发表评论

亲,您还没有登陆,暂不能评论哦! 去 登陆 | 注册

博主信息
   
数据加载中,请稍候...
文章分类
   
数据加载中,请稍候...
阅读排行
 
数据加载中,请稍候...
评论排行
 
数据加载中,请稍候...

Copyright © 叮叮声的奶酪 版权所有
备案号:鄂ICP备17018671号-1

鄂公网安备 42011102000739号