Unveiling the Inner Workings of @EnableAutoConfiguration in Spring Boot

This article dissects the processing flow of Spring Boot's @EnableAutoConfiguration annotation, revealing how AutoConfigurationImportSelector and DeferredImportSelector collaborate to load, filter, and order auto‑configuration classes based on metadata, conditions, and explicit exclusions.

Programmer DD
Programmer DD
Programmer DD
Unveiling the Inner Workings of @EnableAutoConfiguration in Spring Boot

Introduction

In our work we often use the @EnableAutoConfiguration annotation directly or indirectly.

Today we discuss the processing logic of @EnableAutoConfiguration.

Finding the Core Class

Annotations that start with @Enable usually have an @Import that points to the implementation class. For @EnableAutoConfiguration the @Import brings in AutoConfigurationImportSelector , which is the entry point.

The class hierarchy shows that AutoConfigurationImportSelector imports AutoConfigurationImportSelector.AutoConfigurationGroup and related classes.

The Aware series are used for resource injection, and Ordered handles sorting.

DeferredImportSelector runs after all @Configuration beans, allowing it to skip already loaded auto‑configuration classes.

process

private static class DeferredImportSelectorGrouping {<br/>    private final DeferredImportSelector.Group group;<br/>    public Iterable<Group.Entry> getImports() {<br/>        for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {<br/>            this.group.process(deferredImport.getConfigurationClass().getMetadata(),<br/>                deferredImport.getImportSelector());<br/>        }<br/>        return this.group.selectImports();<br/>    }<br/>}

Key steps:

ImportSelector parsing is handled in ConfigurationClassParser#processImports, where DeferredImportSelector is queued.

DeferredImportSelector handling occurs in ConfigurationClassParser#parse via deferredImportSelectorHandler.process().

AutoConfigurationImportSelector.AutoConfigurationGroup.process

and selectImports are the core methods.

1. getAutoConfigurationMetadata()

public AutoConfigurationMetadata getAutoConfigurationMetadata() {<br/>    if (this.autoConfigurationMetadata == null) {<br/>        this.autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);<br/>    }<br/>    return this.autoConfigurationMetadata;<br/>}

This loads the metadata from META-INF/spring-autoconfigure-metadata.properties.

2. getAutoConfigurationEntry()

protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata meta, AnnotationMetadata am) {<br/>    if (!isEnabled(am)) {<br/>        return EMPTY_ENTRY;<br/>    }<br/>    AnnotationAttributes attributes = getAttributes(am);<br/>    List<String> configurations = getCandidateConfigurations(am, attributes);<br/>    configurations = removeDuplicates(configurations);<br/>    Set<String> exclusions = getExclusions(am, attributes);<br/>    checkExcludedClasses(configurations, exclusions);<br/>    configurations.removeAll(exclusions);<br/>    configurations = filter(configurations, meta);<br/>    fireAutoConfigurationImportEvents(configurations, exclusions);<br/>    return new AutoConfigurationEntry(configurations, exclusions);<br/>}

It obtains annotation attributes, candidate configurations, removes duplicates, applies exclusions, filters with conditions, and fires import events.

getCandidateConfigurations

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {<br/>    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());<br/>    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories.");<br/>    return configurations;<br/>}

Loads factory names from META-INF/spring.factories.

filter

private List<String> filter(List<String> configurations, AutoConfigurationMetadata meta) {<br/>    String[] candidates = StringUtils.toStringArray(configurations);<br/>    boolean[] skip = new boolean[candidates.length];<br/>    boolean skipped = false;<br/>    for (AutoConfigurationImportFilter filter : getAutoConfigurationImportFilters()) {<br/>        invokeAwareMethods(filter);<br/>        boolean[] match = filter.match(candidates, meta);<br/>        for (int i = 0; i < match.length; i++) {<br/>            if (!match[i]) {<br/>                skip[i] = true;<br/>                candidates[i] = null;<br/>                skipped = true;<br/>            }<br/>        }<br/>    }<br/>    if (!skipped) {<br/>        return configurations;<br/>    }<br/>    List<String> result = new ArrayList<>(candidates.length);<br/>    for (int i = 0; i < candidates.length; i++) {<br/>        if (!skip[i]) {<br/>            result.add(candidates[i]);<br/>        }<br/>    }<br/>    return result;<br/>}

Implementations such as OnClassCondition, OnBeanCondition, and OnWebApplicationCondition decide which configurations to keep.

sortAutoConfigurations

private List<String> sortAutoConfigurations(Set<String> configurations, AutoConfigurationMetadata meta) {<br/>    return new AutoConfigurationSorter(getMetadataReaderFactory(), meta).getInPriorityOrder(configurations);<br/>}

Sorting follows alphabetical order, then @AutoConfigureOrder, then @AutoConfigureBefore / @AutoConfigureAfter.

Summary

The core processor of @EnableAutoConfiguration is AutoConfigurationImportSelector .

AutoConfigurationImportSelector implements DeferredImportSelector .

ImportSelector parsing occurs in ConfigurationClassParser#processImports, queuing the selector for later handling.

AutoConfigurationImportSelector.AutoConfigurationGroup.process

and selectImports are the focal methods. ConfigurationClassParser#doProcessConfigurationClass uses conditionEvaluator.shouldSkip(...) to apply various @Conditional annotations, enabling custom configurations to override auto‑configuration.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Spring BootDeferredImportSelectorAutoConfigurationImportSelector@EnableAutoConfiguration
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.