必须用到的枚举工具类
定义ENV枚举
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| @Slf4j public enum ENV implements IEnums<String> { RELEASE("正式", "release", "prod"), PRE("预发", "pre"), TEST("测试", "test", "test1", "test2", "test3"), DEV("dev", "dev"), LOCAL("本地", "local"), ;
private final String[] envs; private final String doc;
ENV(String doc, String... envs) { this.envs = envs; this.doc = doc; }
private static ENV CURRENT_ENV;
private static void setCurrentEnv(ENV env) { if (CURRENT_ENV != null && CURRENT_ENV != env) { System.out.println("ENV只能赋值一次,请查看spring容器配置是否正确"); System.err.println("ENV只能赋值一次,请查看spring容器配置是否正确"); log.error("ENV只能赋值一次,请查看spring容器配置是否正确"); System.exit(1); } CURRENT_ENV = env; System.out.println("当前启动环境:" + CURRENT_ENV); log.warn("当前启动环境:" + CURRENT_ENV); }
public static boolean isProd() { return Objects.equals(getENV(), RELEASE); }
public static boolean isDEV() { return Objects.equals(getENV(), DEV); }
public static boolean isDevOrTest() { return isDEV() || Objects.equals(getENV(), TEST); }
private static ENV getENV() { Assert.notNull(CURRENT_ENV, "环境还未初始化,请确认代码顺序"); return CURRENT_ENV; }
@Override public String[] getIdentities() { return envs; }
@Override public String getDoc() { return doc; } }
|
定义spring listener 推断程序的环境
先要在factories文件配置此类的监听
1 2
| org.springframework.context.ApplicationListener=com.DecideENVProcessor
|
java推断逻辑的代码
springBoot容器启动流程
ApplicationContextInitializedEvent 事件是容器上下文准备初始化的时候进行调用,此事件代表之前的environment,已经初始化完毕
environment主要流程解析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public static class DecideENVProcessor implements ApplicationListener<ApplicationContextInitializedEvent> {
private static final AtomicBoolean initialized = new AtomicBoolean(false);
@Override public void onApplicationEvent(ApplicationContextInitializedEvent event) { ConfigurableEnvironment environment = event.getApplicationContext().getEnvironment(); if (environment.getActiveProfiles().length == 0) { return; } if (!initialized.compareAndSet(false, true)) { return; } ENV env = IEnums.getEnum(ENV.class, environment.getActiveProfiles()[0], RELEASE); ENV.setCurrentEnv(env); } }
|
这样在ApplicationContextInitializedEvent事件之后的逻辑,直接调用枚举Env,用来处理不同的业务逻辑即可。
虽然直接用
1 2 3 4
| @Autowired Environment env;
boolean isDev = Objects.eqalse("dev", env.getActiveProfiles()[0]);
|
也能实现,但是这用容易写错,后期也不易于维护。更多的缺点你懂得。。。
总结
我们用通用枚举实现配置我们各个不同的环境的env枚举。
然后再监听spring 容器启动事件,获取Environment的activeProfiles,存到上下文当中,这样我们在后续的工作后期写代码中,用起来特别的方便。