404 Not Found

404 Not Found


nginx

How Spring Boot Auto-Configuration Works

Automatic configuration is the heart of Spring Boot—it automatically registers beans based on the classes in the classpath, allowing you to follow the "convention over configuration" principle.

1. What You'll Learn


2. A True Story from a Framework Developer

(1) Pain Point: Having to write a bunch of configuration settings every time you integrate

Alice's team needs to integrate a new payment SDK into OrderFlow. Every time they integrate a new component, they have to write a @Configuration class, declare beans, configure properties, and handle conditional loading. Bob, a member of the team, often works late into the night due to bean conflicts and circular dependencies; just configuring a single Redis integration took him three days.

(2) Solutions for Automatic Configuration

Spring Boot Starter simplifies "integrating a component" to "adding a dependency":

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

Once you add this dependency, the Redis connection factory and RedisTemplate are both automatically configured.

(3) Revenue

After Alice created the OrderFlow custom starter, new team members can integrate the payment SDK by simply adding a single dependency—there's no longer any need to manually configure any beans, and integration time has been reduced from 3 days to 30 minutes.


3. Automatic Configuration Loading Mechanism

(1) From @EnableAutoConfiguration to AutoConfiguration.imports

100%
flowchart LR
    A["@EnableAutoConfiguration"] --> B["Import<br/>AutoConfigurationImportSelector"]
    B --> C["Read<br/>META-INF/spring/<br/>AutoConfiguration.imports"]
    C --> D["Filter via<br/>@Conditional<br/>Annotations"]
    D --> E["Register<br/>Qualified<br/>Auto-Configuration Classes"]
Version Load File Format
Spring Boot 2.x META-INF/spring.factories key=class1,class2
Spring Boot 3.x META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports One fully qualified class name per line
📌 Key Point: Spring Boot 3.x uses the new AutoConfiguration.imports file and no longer uses spring.factories to register auto-configuration.

(2) The Nature of Auto-Configuration Classes

An auto-configuration class is a @Configuration class with conditional annotations:

(1) ▶ Example: Simplifying the source code for DataSource auto-configuration

JAVA
@AutoConfiguration
@ConditionalOnClass(DataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {

    @Bean
    @ConfigurationProperties("spring.datasource")
    public DataSource dataSource(DataSourceProperties properties) {
        return DataSourceBuilder.create()
            .url(properties.getUrl())
            .username(properties.getUsername())
            .password(properties.getPassword())
            .build();
    }
}

Output:

TEXT
// Execution successful

4. A Detailed Explanation of Conditional Annotations

(1) Core Condition Annotations

Note Conditions Typical Applications
@ConditionalOnClass The specified class exists in the classpath It only takes effect after the dependency is included
@ConditionalOnMissingClass Class not found in classpath Provide an alternative when a dependency is missing
@ConditionalOnBean A specified bean exists in the container Used when depending on other beans
@ConditionalOnMissingBean The specified bean does not exist in the container Provide a default bean; yield to user-defined beans when available
@ConditionalOnProperty Configuration properties meet the conditions Control functions via configuration switches

(1) ▶ Example: @ConditionalOnProperty Toggle Control

JAVA
@Configuration
@ConditionalOnProperty(
    prefix = "orderflow.notification",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = false
)
public class NotificationConfig {

    @Bean
    public NotificationService emailNotificationService() {
        return new EmailNotificationService();
    }
}

Output:

TEXT
// Execution successful
YAML
orderflow:
  notification:
    enabled: true   # Set false to disable notification

(2) ▶ Example: @ConditionalOnMissingBean provides a default implementation

JAVA
@Configuration
public class OrderFlowAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean(IdGenerator.class)
    public IdGenerator uuidIdGenerator() {
        return new UuidIdGenerator();
    }

    @Bean
    @ConditionalOnMissingBean(OrderNumberGenerator.class)
    @ConditionalOnProperty(
        prefix = "orderflow.order",
        name = "number-prefix",
        havingValue = "ORD",
        matchIfMissing = true
    )
    public OrderNumberGenerator defaultOrderNumberGenerator() {
        return new SequentialOrderNumberGenerator("ORD");
    }
}

Output:

TEXT
// Execution successful

5. Custom Starter

(1) Starter Naming Conventions

Type Naming Convention Example
Official Starter spring-boot-starter-* spring-boot-starter-web
Third-Party Starter *-spring-boot-starter orderflow-spring-boot-starter

(2) Starter Project Structure

TEXT
orderflow-spring-boot-starter/
├── src/main/
│   ├── java/com/orderflow/autoconfigure/
│   │   ├── OrderFlowAutoConfiguration.java
│   │   └── OrderFlowProperties.java
│   └── resources/
│       └── META-INF/spring/
│           └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
└── pom.xml

(1) ▶ Example: Complete code for a custom Starter

JAVA
// OrderFlowProperties.java
@ConfigurationProperties(prefix = "orderflow.notification")
public record OrderFlowNotificationProperties(
    boolean enabled,
    String fromEmail,
    String templatePath
) {}

// OrderFlowAutoConfiguration.java
@AutoConfiguration
@ConditionalOnClass(JavaMailSender.class)
@ConditionalOnProperty(
    prefix = "orderflow.notification",
    name = "enabled",
    havingValue = "true"
)
@EnableConfigurationProperties(OrderFlowNotificationProperties.class)
public class OrderFlowAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean(NotificationService.class)
    public NotificationService notificationService(
            OrderFlowNotificationProperties props) {
        return new EmailNotificationService(
            props.fromEmail(),
            props.templatePath()
        );
    }
}

Output:

TEXT
Execution successful
TEXT
# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.orderflow.autoconfigure.OrderFlowAutoConfiguration

6. Debugging and Troubleshooting Automatic Configuration

(1) --debug mode

When you add the --debug parameter at startup, Spring Boot outputs an auto-configuration report:

BASH
java -jar orderflow-service.jar --debug

(1) ▶ Example: Interpreting the Automatic Configuration Report

TEXT
============================
CONDITIONS EVALUATION REPORT
============================

Positive matches:
-----------------
   DataSourceAutoConfiguration matched:
      - @ConditionalOnClass found required class 'javax.sql.DataSource'

Negative matches:
-----------------
   ActiveMQAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory'

Exclusions:
-----------
   None

Unconditional classes:
----------------------
   org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration

Output:

TEXT
Execution successful
Report Area Meaning
Positive matches Automatic configurations that meet the criteria and are active
Negative matches Automatic configurations that do not meet the criteria and are not in effect
Exclusions Explicitly Excluded Auto-Configurations
Unconditional Classes Automatic Configuration for Unconditional Registration

(2) Exclude automatic configuration

(2) ▶ Example: Excluding Unwanted Automatic Configurations

JAVA
// Method 1: Annotation exclusion
@SpringBootApplication(exclude = {
    DataSourceAutoConfiguration.class,
    HibernateJpaAutoConfiguration.class
})
public class OrderFlowApplication { ... }

// Method 2: Configuration property
// application.yml
spring:
  autoconfigure:
    exclude:
      - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

Output:

TEXT
// Execution successful
Exclusion Method Applicable Scenarios Flexibility
@SpringBootApplication(exclude) Always Exclude Determined at Compile Time
spring.autoconfigure.exclude Exclude by environment Runtime-variable
@ConditionalOnProperty Exclude by criteria Most flexible

7. Comprehensive Example: Complete Implementation of the OrderFlow Notification Starter

JAVA
// orderflow-notification-spring-boot-starter

// OrderFlowNotificationProperties.java
package com.orderflow.autoconfigure;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "orderflow.notification")
public record OrderFlowNotificationProperties(
    boolean enabled,
    String fromEmail,
    String templatePath,
    SmtpConfig smtp
) {
    public record SmtpConfig(String host, int port, boolean ssl) {}
}

// NotificationService.java
package com.orderflow.autoconfigure;

public interface NotificationService {
    void send(String to, String subject, String body);
}

// EmailNotificationService.java
package com.orderflow.autoconfigure;

public class EmailNotificationService implements NotificationService {
    private final String fromEmail;
    private final String templatePath;

    public EmailNotificationService(String fromEmail, String templatePath) {
        this.fromEmail = fromEmail;
        this.templatePath = templatePath;
    }

    @Override
    public void send(String to, String subject, String body) {
        // Email sending logic
        System.out.printf("Send to %s: [%s] %s%n", to, subject, body);
    }
}

// OrderFlowNotificationAutoConfiguration.java
package com.orderflow.autoconfigure;

import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

@AutoConfiguration
@ConditionalOnClass(name = "org.springframework.mail.javamail.JavaMailSender")
@ConditionalOnProperty(prefix = "orderflow.notification", name = "enabled", havingValue = "true")
@EnableConfigurationProperties(OrderFlowNotificationProperties.class)
public class OrderFlowNotificationAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean(NotificationService.class)
    public NotificationService notificationService(OrderFlowNotificationProperties props) {
        return new EmailNotificationService(props.fromEmail(), props.templatePath());
    }
}
TEXT
# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.orderflow.autoconfigure.OrderFlowNotificationAutoConfiguration

❓ FAQ

Q Do automatic and manual configurations conflict?
A No. Automatic configuration classes make extensive use of @ConditionalOnMissingBean. If you manually define a Bean of the same type, the automatic configuration will automatically yield to it. This is the "user-defined takes precedence" principle.
Q Why isn't my auto-configuration taking effect?
A Common causes: 1) A dependency class is missing from the classpath; 2) The @ConditionalOnProperty condition is not met; 3) The path or content of the AutoConfiguration.imports file is incorrect; 4) The auto-configuration class is not within the component's scan scope (but auto-configuration is loaded via the imports file and does not require scanning).
Q Can spring.factories still be used?
A Spring Boot 3.x still supports spring.factories for backward compatibility, but you should prioritize using AutoConfiguration.imports files to register auto-configurations. spring.factories will be removed in future versions.
Q How many modules does a custom Starter require?
A Typically two: 1) the autoconfigure module (autoconfiguration code); 2) the starter module (pom.xml that aggregates dependencies). For simple projects, these can be combined into a single module.
Q How can I see which auto-configurations are currently active?
A 1) Start the application with the --debug parameter to view the report; 2) Check the /actuator/conditions endpoint in Actuator; 3) Search for the AutoConfiguration.imports file in your IDE.
Q What are the risks of excluding automatic configuration?
A Once excluded, the related features will be unavailable, and other automatic configurations that depend on them may fail. Make sure you understand the implications of exclusion; you can verify the dependency chain using debug reports.

📖 Summary


📝 Exercises

  1. Basic Exercise (Difficulty ⭐): Start the OrderFlow project using the --debug mode, list all auto-configuration classes among the "Positive matches," and understand the classpath conditions required for each auto-configuration.

  2. Advanced Exercise (Difficulty: ⭐⭐): Create a orderflow-spring-boot-starter that includes a notification feature controlled by the @ConditionalOnProperty switch, then integrate it into the OrderFlow project and test it.

  3. Challenge (Difficulty: ⭐⭐⭐): Implement an auto-configuration system that supports multiple implementations—use Kafka notifications if Kafka is present in the classpath, email notifications otherwise, and log notifications if neither is available. Consider the priority and mutual exclusion design of conditional annotations.

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏