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

有一个问题要求记录活动配置,有一个正确的答案,但问题是只有在所有bean都被正确实例化的情况下才会记录配置。 如果应用程序在启动时崩溃,我甚至(主要)记录所有属性。 我的问题更具体:

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

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

当SpringApplication启动并且ApplicationContext已完全准备但未刷新时,[ApplicationPreparedEvent是一个发布的[]。 将加载bean定义,并且环境已准备好在此阶段使用。

主要方法如下:

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

我重用了当前问题中引用的答案代码,但我修改了它,因为您获得的上下文尚未刷新,并且环境结构与应用程序启动后的结构不完全相同。 我还按属性源打印了属性:一个用于系统环境,一个用于系统属性,一个用于应用程序配置属性等…

 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 { private static final Logger log = LoggerFactory.getLogger(PropertiesLogger.class); private ConfigurableEnvironment environment; @Override public void onApplicationEvent(ApplicationPreparedEvent event) { environment = event.getApplicationContext().getEnvironment(); printProperties(); } 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 findPropertiesPropertySources() { List propertiesPropertySources = new LinkedList<>(); for (PropertySource propertySource : environment.getPropertySources()) { if (propertySource instanceof EnumerablePropertySource) { propertiesPropertySources.add((EnumerablePropertySource) propertySource); } } return propertiesPropertySources; } }