java - 如何在 beans 实例化之前记录 spring boot 应用程序的所有 Activity 属性?

标签 java spring spring-boot logging startup

已经有一个question要求记录 Activity 配置,有一个正确的 answer但问题是只有在正确实例化所有 bean 时才会记录配置。即使应用程序在启动时崩溃,我也想记录所有属性(主要是)。我的问题更具体:

如何在 beans 实例化 之前记录 spring boot 应用程序的所有 Activity 属性?

最佳答案

为此,您需要注册 ApplicationListener .要捕获的事件是 ApplicationPreparedEvent ,根据文档:

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 issue #8899了解详情。

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;
  }
}

关于java - 如何在 beans 实例化之前记录 spring boot 应用程序的所有 Activity 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48212761/

相关文章:

spring-boot - 从数据库加载 clientId 和 clientSecret

java - Spring-boot Rest api页面调用

java - 在hadoop reducer中执行context.write()时出现空指针异常

java - 如何在 Android 布局上正确分配 4 个按钮

Java XML 验证和 MTOM

java - 在可以避免的情况下需要在迭代时手动同步 Synchronized 列表吗?

java - 为什么我无法从模型中检索属性,但可以从 JSP 中检索属性?

spring - 运行 spring 应用程序时出现 java.lang.NoClassDefFoundError

java - 在 spring boot 应用程序上增加 max-http-header-size 是否有危险/影响?

Spring框架。如何存储一些数据以防止每次访问数据库