内容简介:为基于spring-boot的应用添加根据运行时操作系统环境来提示用户选择active profile的功能
spring-boot 有一个根据 JVM 变量 -Dspring.profiles.active 来设置运行时的active profile的功能,但是有些时候我们也许会不小心忘记设置这个变量,这样在生产环境中会带来一定的困扰,所以我想了一个办法,来给忘记设置 -Dspring.profiles.active 的 程序员 一次“secend chance”。
先来讲一下思路:
- step0 约定好profiles的命名,“development”代表开发环境(也可以将默认的profile设为开发环境),“production”代表生产环境
- step1 判断是否设置了
-Dspring.profiles.active,如果已经设置,直接跳转step3 - step2 判断当前操作系统环境,如果不是 Linux 环境则认定为开发环境,自动倒计时激活开发的profile;如果是Linux环境则认定为生产环境,输出选择profile的控制台信息,并等待用户控制台输入进行选择,并依据用户选择来激活profile
- step3
SpringApplication.run()
代码如下:
spring-boot配置文件(使用了默认profile作为开发环境):
spring:
application:
name: comchangyoueurekaserver #注意命名要符合RFC 2396,否则会影响服务发现 详见https://stackoverflow.com/questions/37062828/spring-cloud-brixton-rc2-eureka-feign-or-rest-template-configuration-not-wor
server:
port: 8001
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}
---
spring:
profiles: production
application:
name: comchangyoueurekaserver
server:
port: 8001
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}
BootStarter 封装了 step1 - step3 的逻辑:
import org.apache.commons.lang3.StringUtils;
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import java.util.regex.Pattern;
public class BootStarter {
//用于后续Spring Boot操作的回调
public interface Callback {
void bootRun();
}
private boolean enableAutomaticallyStart = true;
private int automaticallyStartDelay = 3;
public boolean isEnableAutomaticallyStart() {
return enableAutomaticallyStart;
}
public void setEnableAutomaticallyStart(boolean enableAutomaticallyStart) {
this.enableAutomaticallyStart = enableAutomaticallyStart;
}
public int getAutomaticallyStartDelay() {
return automaticallyStartDelay;
}
public void setAutomaticallyStartDelay(int automaticallyStartDelay) {
this.automaticallyStartDelay = automaticallyStartDelay;
}
public void startup(boolean enableAutomaticallyStart, int automaticallyStartDelay, Callback callback) {
if (StringUtils.isBlank(System.getProperty("spring.profiles.active"))) { //如果没有通过参数spring.profiles.active设置active profile则让用户在控制台自己选择
System.out.println("***Please choose active profile:***\n\tp: production\n\td: development");
Timer timer = new Timer();
if (enableAutomaticallyStart && System.getProperty("os.name").lastIndexOf("Linux") == -1) { //如果当前操作系统环境为非Linux环境(一般为开发环境)则automaticallyChooseThreshold秒后自动选择d
System.out.printf("\nSystem will automatically select 'd' in %d seconds.\n", automaticallyStartDelay);
final int[] count = {automaticallyStartDelay};
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
if (count[0]-- == 0) {
System.setProperty("spring.profiles.active", System.getProperty("os.name").lastIndexOf("Linux") == -1 ? "development" : "production");
timer.cancel();
callback.bootRun();
}
}
}, 0, 1000);
}
Pattern pattern = Pattern.compile("^p|d$");
Scanner scanner = new Scanner(System.in);
//如果是Linux系统(一般为生产环境)则强制等待用户输入(一般是忘记设置spring.profiles.active了,这等于给了设置active profile的"second chance")
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (!pattern.matcher(line).find()) {
System.out.println("INVALID INPUT!");
} else {
timer.cancel();
System.setProperty("spring.profiles.active", line.equals("d") ? "development" : "production");
break;
}
}
}
//如果已经通过参数spring.profiles.active设置了active profile直接启动
callback.bootRun();
}
public void startup(Callback callback) {
startup(this.enableAutomaticallyStart, this.automaticallyStartDelay, callback);
}
}
main():
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.context.ApplicationContext;
@EnableEurekaServer
@SpringBootApplication
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
public static void main(String[] args) {
new BootStarter().startup(() -> {
ApplicationContext applicationContext = SpringApplication.run(App.class, args);
for (String activeProfile : applicationContext.getEnvironment().getActiveProfiles()) {
LOGGER.warn("***Running with profile: {}***", activeProfile);
}
});
}
}
运行效果(开发环境Mac OS):
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
赛博空间的奥德赛
(荷兰)约斯·德·穆尔 (Jos de Mul) / 麦永雄 / 广西师范大学出版社 / 2007-2 / 38.00元
本书揭示了数码信息时代的电子传媒与赛博空间为人类历史的发展提供的新的可能性。本书第一部分“通向未来的高速公路”,涉及无线想象、政治技术和极权主义在赛博空间的消解等题旨;第二部分“赛博空间的想象” ,讨论空间文学探索简史、电影和文化的数码化;第三部分”可能的世界” ,关涉世界观的信息化、数码复制时代的世界、数码此在等层面;第四、五部分探讨主页时代的身份、虚拟人类学、虚拟多神论、赛博空间的进化、超人文......一起来看看 《赛博空间的奥德赛》 这本书的介绍吧!