SpringBoot中获取spring.profiles.active的值

SpringBoot中获取spring.profiles.active的值

SpringBoot通过@Profile("dev") 可以在配置类中限定配置环境,在实际开发中可能需要方法级别的控制,也就是说获取到当前环境的具体信息

最终通过查看SpringBoot日志以及源码找到答案

  • SpringBoot启动日志中有下面这句:
15:57:56.128 [restartedMain] INFO  c.d.o.OptplatformApplication - The following profiles are active: dev
  • 跟踪代码:SpringApplication.run方法
public ConfigurableApplicationContext run(String... args) {        StopWatch stopWatch = new StopWatch();        stopWatch.start();        ConfigurableApplicationContext context = null;        FailureAnalyzers analyzers = null;        configureHeadlessProperty();        SpringApplicationRunListeners listeners = getRunListeners(args);        listeners.starting();        try {            ApplicationArguments applicationArguments = new DefaultApplicationArguments(                    args);            ConfigurableEnvironment environment = prepareEnvironment(listeners,                    applicationArguments);            Banner printedBanner = printBanner(environment);            context = createApplicationContext();            analyzers = new FailureAnalyzers(context);            prepareContext(context, environment, listeners, applicationArguments,                    printedBanner);  // 在这里打印了,跟踪进去            refreshContext(context);            afterRefresh(context, applicationArguments);            listeners.finished(context, null);            stopWatch.stop();            if (this.logStartupInfo) {                new StartupInfoLogger(this.mainApplicationClass)                        .logStarted(getApplicationLog(), stopWatch);            }            return context;        }        catch (Throwable ex) {            handleRunFailure(context, listeners, analyzers, ex);            throw new IllegalStateException(ex);        }    }
  • 跟踪代码:SpringApplication.prepareContext方法
private void prepareContext(ConfigurableApplicationContext context,      ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,      ApplicationArguments applicationArguments, Banner printedBanner) {   context.setEnvironment(environment);   postProcessApplicationContext(context);   applyInitializers(context);   listeners.contextPrepared(context);   if (this.logStartupInfo) {      logStartupInfo(context.getParent() == null);      logStartupProfileInfo(context);  // 名称很明显,继续跟踪进去   }   ......}
  • 跟踪代码:SpringApplication.logStartupProfileInfo方法
protected void logStartupProfileInfo(ConfigurableApplicationContext context) {    Log log = getApplicationLog();   if (log.isInfoEnabled()) {      String[] activeProfiles = context.getEnvironment().getActiveProfiles();      if (ObjectUtils.isEmpty(activeProfiles)) {         String[] defaultProfiles = context.getEnvironment().getDefaultProfiles();         log.info("No active profile set, falling back to default profiles: "               + StringUtils.arrayToCommaDelimitedString(defaultProfiles));       }      else {         log.info("The following profiles are active: "               + StringUtils.arrayToCommaDelimitedString(activeProfiles));  //找到了,很明显用了ApplicationContxt容器,接下来就是写个工具类来获取Application就行啦。      }   }}
  • 编写SpringContextHolder工具类
@Slf4jpublic class SpringContextHolder implements ApplicationContextAware, DisposableBean {    private static ApplicationContext applicationContext = null;    /**     * 取得存储在静态变量中的ApplicationContext.     */    public static ApplicationContext getApplicationContext() {        assertContextInjected();        return applicationContext;    }    /**     * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.     */    public static <T> T getBean(String name) {        assertContextInjected();        return (T) applicationContext.getBean(name);    }    /**     * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.     */    public static <T> T getBean(Class<T> requiredType) {        assertContextInjected();        return applicationContext.getBean(requiredType);    }    /**     * 检查ApplicationContext不为空.     */    private static void assertContextInjected() {        if (applicationContext == null) {            throw new IllegalStateException("applicaisetApplicationContexttonContext属性未注入, 请在applicationContext" +                    ".xml中定义SpringContextHolder或在SpringBoot启动类中注册SpringContextHolder.");        }    }    /**     * 获取当前环境     * @return     */    public static String getActiveProfile() {        return applicationContext.getEnvironment().getActiveProfiles()[0];    }    /**     * 清除SpringContextHolder中的ApplicationContext为Null.     */    public static void clearHolder() {        log.debug("清除SpringContextHolder中的ApplicationContext:"                + applicationContext);        applicationContext = null;    }    @Override    public void destroy() throws Exception {        SpringContextHolder.clearHolder();    }    @Override    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {        if (SpringContextHolder.applicationContext != null) {            log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext);        }        SpringContextHolder.applicationContext = applicationContext;    }}
  • 使用示例

可以通过改方式来控制在测试环境打印出当前访问的接口URL

  if ("dev".equals(SpringContextHolder.getActiveProfile())) {            System.out.println(String.format("====当前接口URL: %s", request.getRequestURL()));        }
转自:https://www.jianshu.com/p/a97aba019b3c
免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部