Skip to content

Print out configuration class import tree/order during application startup #37156

Description

@tonny1983

Feature Description

Currently, users relies on --debug flag to diagnose complex Spring Boot configuration precedence, condition evaluations, and auto-configurations. It can print out positive and negative condition matches (e.g., @ConditionalOnClass, @ConditionalOnMissingBean) for auto-configuration classes. It explains why a configuration evaluated to true or false, but not which parent configuration or @Import chain pulled it into the context.

There is no native way to visualize the actual configuration class import tree (i.e., showing how @Configuration classes, @Import selectors, inner configurations, and auto-configurations trigger one another hierarchically) directly during application startup.

Adding an optional configuration tree logger would make debugging configuration precedence, custom starter ordering, and bean initialization issues significantly easier.

Motivation / Use Case

When building large modular applications or custom Spring Boot starters, developer issues often stem from:

  1. Understanding why a specific auto-configuration or nested configuration was pulled into the context.
  2. Tracking deep chains of @Import / @ImportSelector / @ImportResource annotations.
  3. Verifying processing precedence among user configurations, @AutoConfigureBefore, and @AutoConfigureAfter.

Proposed Implementation

Implementing this feature is straightforward, as a dedicated logger or tree printer can run during the BeanFactoryPostProcessor or ApplicationListener phase to provide instant visual insight into the configuration structure during startup without extra endpoint queries.

Sample code

@Configuration
public class ConfigurationLoggerConfig implements BeanFactoryPostProcessor {
     private static final Logger log = LoggerFactory.getLogger(ConfigurationLoggerConfig.class);

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        String[] configBeans = beanFactory.getBeanNamesForAnnotation(Configuration.class);
        log.info("=== Registered @Configuration Classes ===");
        for (String name : configBeans) {
            Object configClass = beanFactory.getBeanDefinition(name).getBeanClassName();
            log.info("Config Bean: {} -> {}", name, configClass);
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: coreIssues in core modules (aop, beans, core, context, expression)status: waiting-for-triageAn issue we've not yet triaged or decided on

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions