为基于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-worserver:port: 8001eureka:instance:hostname: localhostclient:registerWithEureka: falsefetchRegistry: falseserviceUrl:defaultZone: http://${eureka.instance.hostname}:${server.port}---
spring:profiles: productionapplication:name: comchangyoueurekaserverserver:port: 8001eureka:instance:hostname: localhostclient:registerWithEureka: falsefetchRegistry: falseserviceUrl: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 = 10;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");final boolean[] started = {false};Timer timer = new Timer();if (enableAutomaticallyStart && System.getProperty("os.name").lastIndexOf("Linux") == -1) { //如果当前操作系统环境为非Linux环境(一般为开发环境)则automaticallyStartDelay秒后自动设置为开发环境System.out.printf("\nSystem will automatically select 'd' in %d seconds.\n", automaticallyStartDelay);final int[] count = {automaticallyStartDelay};timer.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {if (count[0]-- == 0) {timer.cancel();started[0] = true;System.setProperty("spring.profiles.active", "development");callback.bootRun();}}}, 0, 1000);}Scanner scanner = new Scanner(System.in);Pattern pattern = Pattern.compile("^p|d$");//如果是Linux系统(一般为生产环境)则强制等待用户输入(一般是忘记设置spring.profiles.active了,这等于给了设置active profile的"second chance")while (scanner.hasNextLine()) {if (started[0]) {break;}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");callback.bootRun();break;}}} else { //如果已经通过参数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):
扩展: 其实在这里我们还可以发散一下思维,基于spring-boot的应用比起传统spring应用的一大优势是自己可以掌控main()
方法,有了这一点,我们是能玩出很多花样来的,思路不要被局限在tomcat
时代了。
main法在手,天下我有。
2017-1-22更新:增加了线程安全的处理
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 {private volatile boolean started;//用于后续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环境(一般为开发环境)则automaticallyStartDelay秒后自动设置为开发环境System.out.printf("\nSystem will automatically select 'd' in %d seconds.\n", automaticallyStartDelay);timer.scheduleAtFixedRate(new TimerTask() {private ThreadLocal<Integer> countDown = ThreadLocal.withInitial(() -> automaticallyStartDelay);@Overridepublic void run() {if (countDown.get() == 0) {timer.cancel();started = true;System.setProperty("spring.profiles.active", "development");callback.bootRun();}countDown.set(countDown.get() - 1);}}, 0, 1000);}Scanner scanner = new Scanner(System.in);Pattern pattern = Pattern.compile("^p|d$");//如果是Linux系统(一般为生产环境)则强制等待用户输入(一般是忘记设置spring.profiles.active了,这等于给了设置active profile的"second chance")while (scanner.hasNextLine()) {if (started) {break;}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");callback.bootRun();break;}}} else { //如果已经通过参数spring.profiles.active设置了active profile直接启动callback.bootRun();}}public void startup(Callback callback) {startup(this.enableAutomaticallyStart, this.automaticallyStartDelay, callback);}
}复制代码
2017-01-25更新:
补上了 try-with-resource
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 {private volatile boolean started;//用于后续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环境(一般为开发环境)则automaticallyStartDelay秒后自动设置为开发环境System.out.printf("\nSystem will automatically select 'd' in %d seconds.\n", automaticallyStartDelay);timer.scheduleAtFixedRate(new TimerTask() {private ThreadLocal<Integer> countDown = ThreadLocal.withInitial(() -> automaticallyStartDelay);@Overridepublic void run() {if (countDown.get() == 0) {timer.cancel();started = true;System.setProperty("spring.profiles.active", "development");callback.bootRun();}countDown.set(countDown.get() - 1);}}, 0, 1000);}try (Scanner scanner = new Scanner(System.in)) {Pattern pattern = Pattern.compile("^p|d$");//如果是Linux系统(一般为生产环境)则强制等待用户输入(一般是忘记设置spring.profiles.active了,这等于给了设置active profile的"second chance")while (scanner.hasNextLine()) {if (started) {break;}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");callback.bootRun();break;}}}} else { //如果已经通过参数spring.profiles.active设置了active profile直接启动callback.bootRun();}}public void startup(Callback callback) {startup(this.enableAutomaticallyStart, this.automaticallyStartDelay, callback);}
}复制代码
为基于spring-boot的应用添加根据运行时操作系统环境来提示用户选择active profile的功能...相关推荐
- 开源oa_圈子哥推荐一款基于 Spring Boot 开发 OA 开源产品,学习/搞外快都是不二选择!...
点击上方蓝字关注「程序员的技术圈子」 今天圈子哥给大家推荐一套Spring Boot 开发 OA系统,系统功能齐全,不管是用来学习或者搞外快都是不错的选择,clone下来吧! 办公自动化(OA)是面向 ...
- Spring Boot –使用执行器端点在运行时配置日志级别
从Spring Boot 1.5开始,新的loggers器执行器端点允许在运行时查看和更改应用程序记录级别. 将spring-boot-actuator添加到您的项目 <dependency&g ...
- 毕业设计-基于spring boot的智慧物业管理系统
项目描述 这是一个基于spring boot的智慧物业项目,我们的项目实现了用户登录.投诉.保修功能,以及后台物业管理功能.用户可以通过登录界面登录系统,提交投诉或保修请求.管理员可以在后台管理界面查 ...
- 基于Spring Boot 2.0的IoT应用集成和使用CSE实践
本文通过一个IoT的应用展现在Spring Boot 2.0中集成和使用CSE.IoT应用原来使用Spring Boot 2.0开发,通过少量的步骤集成CSE,然后展现了集成后带来了哪些新特性,以及中 ...
- Micronaut for Spring支持Spring Boot应用以Micronaut形式运行
在Micronaut 1.0.1小版本发布的同时,Object Computing, Inc.(OCI)还发布了Micronaut for Spring 1.0 M1.在发布说明中这样写到: Micr ...
- 基于Spring Boot+Cloud构建微云架构
链接:my.oschina.net/u/3636867/blog/1802517 前言 首先,最想说的是,当你要学习一套最新的技术时,官网的英文文档是学习的最佳渠道.因为网上流传的多数资料是官网翻译而 ...
- 基于Spring Boot和Spring Cloud实现微服务架构学习--转
原文地址:http://blog.csdn.net/enweitech/article/details/52582918 看了几周spring相关框架的书籍和官方demo,是时候开始总结下这中间的学习 ...
- 基于 Spring Boot 和 Spring Cloud 实现微服务架构
前言 首先,最想说的是,当你要学习一套最新的技术时,官网的英文文档是学习的最佳渠道.因为网上流传的多数资料是官网翻译而来,很多描述的重点也都偏向于作者自身碰到的问题,这样就很容易让你理解和操作出现偏差 ...
- c# 基于layui的通用后台管理系统_基于spring boot和vuejs的通用后台管理系统脚手架 guns-lite...
Guns-lite 前言 guns-lite是在guns的基础上将数据库层由mybatis替换为spring data jpa的系统. guns-lite是一个基于spring boot的后台管理系统 ...
最新文章
- 局域网无法上网解决处理方法
- android多线程的本质,[原创]分析unidbg(unidbgMutil)多线程机制
- linux 上删除docker 虚悬镜像
- 2021-11-14泛型
- 关于数据准备时,自动棌番的主键,这一字段数据的注意(IT总结之五)
- Dapper Sqlpara where in
- 李宏毅机器学习——半监督学习
- Leetcode10. Regular Expression Matching
- 深度图像配准_巧解图像处理经典难题之图像配准
- 一信通短信接口对接_实例分享:验证码短信接口如何对接?接口api哪个好用?...
- AE2017 安-装-破-解
- 华为手机老是自动截屏_华为手机竟然三种截屏方法 然后打开智能截屏开关
- 如何在直播、会议、视频中使用虚拟形象
- arm linux 掉电检测,如何实现单片机掉电检测与数据掉电保存?-嵌入式系统-与非网...
- usb计算机采集卡,关于usb视频采集卡 hdmi设置你可能不知道
- 黑客攻防日记---刘欣
- 机器学习-数据科学库 13 政治献金数据案例
- JWT 详解及源码分析
- 表示颜色的英语单词(图)
- 10---字符个数统计
热门文章
- java 字符串为空_java判断字符串为空,方法详解
- 22_python基础—异常
- Linux(二):VMware虚拟机中Ubuntu安装详细过程
- PHP条件语句总结,php条件语句的总结
- python 字典由值找键_python字典怎么根据值返回键
- python源程序文件的扩展名_python程序文件扩展名知识点详解
- java 与 .net socket_java.net.ServerSocket和java.net.Socket
- 台风路径超级计算机,厄尔尼诺又要来了?2号台风或要生成,超级计算机:路径争议大...
- 可以方便的将SQL语句的执行结果显示成表格结果的JAVA类,可以用于不同的数据显示
- 客户端产生CLOSE_WAIT状态的解决方案