How Spring Boot Auto-Configuration Works: From @EnableAutoConfiguration to Bean Loading

This article explains Spring Boot's auto‑configuration mechanism, covering how @EnableAutoConfiguration loads configuration classes, the role of @AutoConfigurationPackage and @Import, the processing of spring.factories and metadata files, and how the main application class is registered in the IoC container.

政采云技术
政采云技术
政采云技术
How Spring Boot Auto-Configuration Works: From @EnableAutoConfiguration to Bean Loading

What is Auto‑Configuration?

Auto‑configuration is a core Spring Boot feature that automatically registers beans into the IoC container, reducing the need for manual configuration.

Adding a New Module (e.g., Redis)

Include the starter dependency in pom.xml.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Add Redis properties to application.properties.

spring.redis.host=127.0.0.1
spring.redis.port=6379

Inject RedisTemplate in your code.

@Autowired
private RedisTemplate<String, String> redisTemplate;

RedisTemplate is injected because auto‑configuration registers it as a bean.

Auto‑Configuration Process

@EnableAutoConfiguration

@SpringBootApplication

includes @EnableAutoConfiguration, which loads all eligible configuration classes into the IoC container.

The annotation consists of two parts:

@AutoConfigurationPackage – defines the package range to scan for @Component, @Service, etc. By default it is the package of the main class.

@Import(AutoConfigurationImportSelector.class) – imports third‑party configuration classes.

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration { ... }

@AutoConfigurationPackage

Registers the specified package with DefaultListableBeanFactory during bean registration, allowing beans in that package to be discovered.

AutoConfigurationImportSelector

Implements ImportSelector and selects candidate configurations based on metadata.

@Override
public String[] selectImports(AnnotationMetadata metadata) {
    // 1. Load spring‑autoconfigure‑metadata.properties
    // 2. Get @SpringBootApplication attributes
    // 3. Load META-INF/spring.factories via SpringFactoriesLoader
    // 4. Remove duplicates
    // 5. Apply @ConditionalOnClass filters
    // 6. Exclude classes defined in @Import(exclude=...)
    // 7. Return the remaining class names
}

Key files: spring.factories lists 109 candidate configuration classes. spring-autoconfigure-metadata.properties defines @ConditionalOnClass rules, reducing the actual loads to 31 classes.

Spring uses the SPI (Service Provider Interface) mechanism to load these classes lazily.

@Import Analysis

Three ways to use @Import

Import a regular class directly.

@Import(PersonConfig.class)
@Configuration
public class PersonConfiguration { }

Import an ImportSelector implementation.

@Import(TestImportSelector.class)
@Configuration
public class ImportTestConfig { }

public class TestImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata metadata) {
        return new String[]{"com.example.service.TestService"};
    }
}

Import an ImportBeanDefinitionRegistrar implementation.

@Import(TestImportBeanDefinitorSelector.class)
@Configuration
public class ImportBeanDefinitionTestConfig { }

public class TestImportBeanDefinitorSelector implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        BeanDefinition beanDefinition = BeanDefinitionBuilder
            .rootBeanDefinition(Person.class).getBeanDefinition();
        registry.registerBeanDefinition("person", beanDefinition);
    }
}

Implementation Details

ConfigurationClassPostProcessor processes @Import. It implements BeanDefinitionRegistryPostProcessor and its postProcessBeanDefinitionRegistry method parses configuration classes and eventually calls processImports to handle the three import styles.

refresh() -> invokeBeanFactoryPostProcessors() -> postProcessBeanDefinitionRegistry()
    -> parse() -> doProcessConfigurationClass() -> processImports()

Main Class Registration in the IoC Container

prepareContext() → load()

SpringApplication.run() starts the application.

prepareContext() calls load(), which registers the main class via AnnotatedBeanDefinitionReader.

private void prepareContext(ConfigurableApplicationContext context, ...) {
    // ...
    load(context, sources.toArray(new Object[0]));
    // ...
}

Overall Auto‑Configuration Flow

The complete call chain is:

run() -> prepareContext() -> load() -> parse() -> register()

Summary

Understanding the high‑level flow of Spring Boot auto‑configuration—package scanning, import selector processing, and main‑class registration—helps developers navigate the framework efficiently and focus on the essential steps when reading source code.

JavaRedisSpring BootAnnotationsdependency-injectionauto-configuration
政采云技术
Written by

政采云技术

ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.

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.