在bean实例化之前,如何记录Spring Boot应用程序的所有活动属性? [英] How to log all active properties of a spring boot application before the beans instantiation?

查看:84
本文介绍了在bean实例化之前,如何记录Spring Boot应用程序的所有活动属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已经有一个问题要求记录活动配置,有一个正确的 answer ,但问题在于仅在所有情况下都记录配置bean已正确实例化.我想记录所有属性,即使(主要)在应用程序启动时崩溃.我的问题更具体:

There is already a question asking for logging the active configuration, there is a correct answer but the problem is that the configuration is logged only if all beans are correctly instantiated. I would like to log all properties even (mainly) if the application crash at startup. My question is more specific:

如何在bean实例化之前 记录Spring Boot应用程序的所有活动属性?

How to log all active properties of a spring boot application before the beans instantiation?

推荐答案

为此,您需要注册

For doing this you need to register an ApplicationListener. The event to catch is the ApplicationPreparedEvent, according to the documentation:

ApplicationPreparedEvent是在SpringApplication启动时发布的事件,并且 ApplicationContext已准备充分,但未刷新.豆 定义将被加载,环境可以在以下位置使用 这个阶段.

ApplicationPreparedEvent is an event published when a SpringApplication is starting up and the ApplicationContext is fully prepared but not refreshed. The bean definitions will be loaded and the Environment is ready for use at this stage.

主要方法如下:

public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(MyApplication.class);
        springApplication.addListeners(new PropertiesLogger());
        springApplication.run(args);        
}

我已经重用了当前问题中引用的答案的代码,但是我已经对其进行了修改,因为您获得的上下文尚未刷新,并且环境的结构与应用程序启动后的结构不完全相同.我还按属性来源打印了属性:一个用于系统环境,一个用于系统属性,一个用于应用程序配置属性,等等.另请注意,ApplicationPreparedEvent可以多次触发,并且我仅第一次打印属性.有关详细信息,请参见 Spring Boot问题#8899 .

I've reused the code of the answer cited in the current question but I've modified it because the context you get is not already refreshed and the structure of the environment is not exactly the same as after the startup of the application. I've also printed the properties by property sources: one for the the system environment, one for the system properties, one for the application configuration properties, etc... Note also that the ApplicationPreparedEvent can be triggered multiple time, and that I print the properties only the first time. See Spring Boot issue #8899 for details.

package com.toto.myapp.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.PropertySource;

import java.util.LinkedList;
import java.util.List;

public class PropertiesLogger implements ApplicationListener<ApplicationPreparedEvent> {
  private static final Logger log = LoggerFactory.getLogger(PropertiesLogger.class);

  private ConfigurableEnvironment environment;
  private boolean isFirstRun = true;

  @Override
  public void onApplicationEvent(ApplicationPreparedEvent event) {
    if (isFirstRun) {
      environment = event.getApplicationContext().getEnvironment();
      printProperties();
    }
    isFirstRun = false;
  }

  public void printProperties() {
    for (EnumerablePropertySource propertySource : findPropertiesPropertySources()) {
      log.info("******* " + propertySource.getName() + " *******");
      String[] propertyNames = propertySource.getPropertyNames();
      Arrays.sort(propertyNames);
      for (String propertyName : propertyNames) {
        String resolvedProperty = environment.getProperty(propertyName);
        String sourceProperty = propertySource.getProperty(propertyName).toString();
        if(resolvedProperty.equals(sourceProperty)) {
          log.info("{}={}", propertyName, resolvedProperty);
        }else {
          log.info("{}={} OVERRIDDEN to {}", propertyName, sourceProperty, resolvedProperty);
        }
      }
    }
  }

  private List<EnumerablePropertySource> findPropertiesPropertySources() {
    List<EnumerablePropertySource> propertiesPropertySources = new LinkedList<>();
    for (PropertySource<?> propertySource : environment.getPropertySources()) {
      if (propertySource instanceof EnumerablePropertySource) {
        propertiesPropertySources.add((EnumerablePropertySource) propertySource);
      }
    }
    return propertiesPropertySources;
  }
}

这篇关于在bean实例化之前,如何记录Spring Boot应用程序的所有活动属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆