springboot 启动时 获取 profile,并作为static静态变量 使用

如何把 profile 作为静态变量 任意随时使用 无需 @value(“${spring.profiles.acitve”}

看了很多 获取 变量的例子: 大多是用 @value("${spring.profiles.acitve"} 赋值给对象的属性
不满意止步于此,而且对我来说,根本不能用

该方式缺点:@value("${spring.profiles.acitve"}

  1. 不能在 静态方法中使用,不能作为static 变量直接注入后使用,无法提炼到静态工具类方法中。
  2. 不能在 早期使用,必须等待 springcontext 完全加载后,才能使用该对象。原因是 作为对象的属性,必须被容器管理后,才能被调用。当 spring 容器 没有完全启动时,也无法加载该参数。

解决方案: 从Enviroment 获取

  1. 利用 事件监听器,监听早期 spring 加载 Enviroment 环境参数完成的事件 ApplicationEnvironmentPreparedEvent
  2. 该事件包含了 profile 等信息,而且加载时机非常早,在一系列 SpringApplicationEvent 中 仅次于 ApplicationStartingEvent,见下图。 而 ApplicationStartingEvent 因为太过早期,所以不建议使用。
    系列事件
  3. 该事件基本上把 所有的参数,都加载进了 org.springframework.core.env.ConfigurableEnvironment.
    包含如下这些方式配置的参数,优先级如下
    当 springcloud 项目时,config server 从 bootstrap.yml中配置,优先于application.yml 在这里插入图片描述
  4. 加载过程源码解析 在这里插入图片描述
  5. 在步骤4中,就会执行到 我们自定义的 监听器了 。而且可以获取到 该 Environment ,进而获取spring 帮我们整理好的全部参数

代码实现:

  • 自定义监听器的代码如下 SpringApplicationEventListener :

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
    import org.springframework.boot.context.event.SpringApplicationEvent;
    import org.springframework.context.ApplicationListener;
    
    /**
     * 监听 ApplicationEnvironmentPreparedEvent  事件,第一时间 获取 profile 信息, 设置为 static 变量备用 ,一并设置 isProd,isDev,isTest 备用 
     *
     * 代码参考 https://stackoverflow.com/questions/48837173/unable-to-intercept-applicationenvironmentpreparedevent-in-spring-boot
     *
     * @see SpringApplication#prepareEnvironment(org.springframework.boot.SpringApplicationRunListeners, org.springframework.boot.ApplicationArguments)
     *
     * @author stormfeng
     * @date 2022-08-23  16:44
     */
    @Slf4j
    public class SpringApplicationEventListener implements ApplicationListener<SpringApplicationEvent> {
    	//  这几个 静态变量,可以很方便的在其他类中作为工具使用
        public static String profile;
        public static boolean isProd,isDev,isTest;
    
        /**
         * 监听 SpringApplicationEvent
         */
        @Override
        public void onApplicationEvent(SpringApplicationEvent event) {
            log.debug("监听到 SpringApplicationEvent :{}", event.getClass().getSimpleName());
            if (event instanceof ApplicationEnvironmentPreparedEvent) {
                final ApplicationEnvironmentPreparedEvent e = (ApplicationEnvironmentPreparedEvent) event;
                final String[] activeProfiles = e.getEnvironment().getActiveProfiles();
                profile = activeProfiles[0].
                initProfile();
                log.info("监听到 SpringApplicationEvent :{},设置profile :{}", event.getClass().getSimpleName(), profile);
            }
        }
    
        private void initProfile() {
            isProd = "prod".equalsIgnoreCase(profile);
    		isTest = "test".equalsIgnoreCase(profile);
            isDev = "dev".equalsIgnoreCase(profile);
        }
    
  • 此时因springContext尚未完全加载,因此不能使用 @EventListener 自动注入监听器 ,必须手动添加 listeners()

    @SpringBootApplication
    public class BootApplication {
        public static void main(String[] args) {
            new SpringApplicationBuilder(BootApplication.class).listeners(new SpringApplicationEventListener()).build().run(args);
            log.info("----------------------Application start complete--------------------------");
        }
    }
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值