转储 Spring Boot 配置

Posted

技术标签:

【中文标题】转储 Spring Boot 配置【英文标题】:Dump Spring boot Configuration 【发布时间】:2016-02-22 00:41:41 【问题描述】:

我们的运维人员希望在应用启动时将 Spring 引导配置(即所有属性)转储到日志文件中。我假设这可以通过注入带有注释 @ConfigurationProperties 的属性并打印它们来完成。

问题在于是否有更好的或内置的机制来实现这一点。

鉴于似乎没有内置的解决方案,我试图自己做饭。这是我想出的:

@Component
public class ConfigurationDumper 


    @Autowired
    public void init(Environment env)
        log.info("",env);
    


这样做的挑战是它不会打印我的 application.yml 中的变量。相反,这是我得到的:

StandardServletEnvironment 

    activeProfiles=[],
    defaultProfiles=[default],
    propertySources=[
        servletConfigInitParams,
        servletContextInitParams,
        systemProperties,
        systemEnvironment,
        random,
        applicationConfig: [classpath: /application.yml]
    ]

如何解决这个问题,以便加载和打印所有属性?

【问题讨论】:

【参考方案1】:

如果您使用 actuator ,env endpoint 将为您提供在ConfigurableEnvironment 中设置的所有配置属性,configprops 将为您提供@ConfigurationProperties 的列表,但不在日志中。

查看source code 的env 端点,它可能会让您了解如何获取您感兴趣的所有属性。

【讨论】:

【参考方案2】:

没有内置机制,这实际上取决于您所说的“所有属性”是什么意思。您只想要 编写的实际键还是想要所有属性(包括默认值)。

对于前者,您可以轻松收听ApplicationEnvironmentPreparedEvent 并记录您感兴趣的属性来源。对于后者,/configprops 确实是一个更好/完整的输出。

【讨论】:

【参考方案3】:

这仅记录配置的属性 *.properties 文件。

/**
 * maps given property names to its origin
 * @return a map where key is property name and value the origin
 */
public Map<String, String> fromWhere() 
    final Map<String, String> mapToLog = new HashMap<>();

    final MutablePropertySources propertySources = env.getPropertySources();

    final Iterator<?> it = propertySources.iterator();

    while (it.hasNext()) 
        final Object object = it.next();
        if (object instanceof MapPropertySource) 
            MapPropertySource propertySource = (MapPropertySource) object;
            String propertySourceName = propertySource.getName();

            if (propertySourceName.contains("properties")) 

                Map<String, Object> sourceMap = propertySource.getSource();

                for (String key : sourceMap.keySet()) 
                    final String envValue = env.getProperty(key);
                    String env2Val = System.getProperty(key);

                    String source = propertySource.getName().contains("file:") ? "FILE" : "JAR";

                    if (envValue.equals(env2Val)) 
                        source = "ENV";
                    

                    mapToLog.putIfAbsent(key, source);               
                
            
        
    
    return mapToLog;

我的示例输出描述了属性名称、值及其来源。我的属性值描述了它们的来源。:

myprop: fooFromJar from JAR
aPropFromFile: fromExternalConfFile from FILE
mypropEnv: here from vm arg from ENV
ENV 表示我已经通过 -D 将它交给了 JVM。 JAR 表示它来自 JAR 中的 application.properties FILE 表示它来自 JAR 之外的 application.properties

【讨论】:

以上是关于转储 Spring Boot 配置的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot:Spring Boot项目配置详解

Spring boot 默认首页配置 Spring boot web默认首页配置 Spring boot web项目默认首页配置

Spring Boot 揭秘与实战 附录 - Spring Boot 公共配置

初识Spring Boot (Spring Boot配置文件)

Spring Boot Logging 配置

如何在 Spring Boot 应用程序中预编译 jsp?