404 Not Found

404 Not Found


nginx

Spring Boot自動設定の仕組み

自動設定はSpring Bootの心臓部です。クラスパス内のクラスに基づいてBeanを自動登録し, 「設定より規約」の原則に従えるようにします。

1. 学ぶ内容


2. フレームワーク開発者の実話

(1) ペインポイント:コンポーネント統合のたびに大量の設定を書く必要がある

AliceのチームはOrderFlowに新しい支払いSDKを統合する必要があります。新しいコンポーネントを統合するたびに@Configurationクラスを書き, Beanを宣言し, プロパティを設定し, 条件付き読み込みを処理する必要があります。チームメンバーのBobはBeanの競合や循環依存で深夜まで作業することが多く, Redisの統合だけで3日かかりました。

(2) 自動設定による解決策

Spring Boot Starterは「コンポーネントの統合」を「依存関係の追加」に簡素化します。

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

この依存関係を追加するだけで, Redis接続ファクトリとRedisTemplateが自動的に設定されます。

(3) 成果

AliceがOrderFlowのカスタムStarterを作成した後, 新しいチームメンバーは依存関係を1つ追加するだけで支払いSDKを統合できるようになりました。手動でBeanを設定する必要はなくなり, 統合時間は3日から30分に短縮されました。


3. 自動設定読み込みメカニズム

(1) @EnableAutoConfigurationからAutoConfiguration.importsまで

100%
flowchart LR
    A["@EnableAutoConfiguration"] --> B["インポート<br/>AutoConfigurationImportSelector"]
    B --> C["読み込み<br/>META-INF/spring/<br/>AutoConfiguration.imports"]
    C --> D["@Conditional<br/>アノテーションで<br/>フィルタリング"]
    D --> E["条件を満たす<br/>自動設定クラスを<br/>登録"]
バージョン 読み込みファイル 形式
Spring Boot 2.x META-INF/spring.factories key=class1,class2
Spring Boot 3.x META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 1行に1つの完全修飾クラス名
📌 重要ポイント: Spring Boot 3.xは新しいAutoConfiguration.importsファイルを使用し, 自動設定の登録にspring.factoriesは使用しなくなりました。

(2) 自動設定クラスの本質

自動設定クラスは条件アノテーションを持つ@Configurationクラスです。

(1) ▶ サンプル:DataSource自動設定のソースコードの簡略化

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();
    }
}

出力:

TEXT
// 実行成功

4. 条件アノテーションの詳細解説

(1) コア条件アノテーション

アノテーション 条件 代表的な用途
@ConditionalOnClass 指定したクラスがクラスパスに存在する 依存関係が含まれた後にのみ有効
@ConditionalOnMissingClass クラスがクラスパスに見つからない 依存関係がない場合の代替提供
@ConditionalOnBean 指定したBeanがコンテナに存在する 他のBeanに依存する場合に使用
@ConditionalOnMissingBean 指定したBeanがコンテナに存在しない デフォルトBeanを提供。ユーザー定義Beanがあれば譲る
@ConditionalOnProperty 設定プロパティが条件を満たす 設定スイッチで機能を制御

(1) ▶ サンプル:@ConditionalOnPropertyによるスイッチ制御

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

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

出力:

TEXT
// 実行成功
YAML
orderflow:
  notification:
    enabled: true   # falseに設定すると通知を無効化

(2) ▶ サンプル:@ConditionalOnMissingBeanによるデフォルト実装の提供

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");
    }
}

出力:

TEXT
// 実行成功

5. カスタムStarter

(1) Starterの命名規則

タイプ 命名規則
公式Starter spring-boot-starter-* spring-boot-starter-web
サードパーティStarter *-spring-boot-starter orderflow-spring-boot-starter

(2) Starterのプロジェクト構造

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) ▶ サンプル:カスタム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()
        );
    }
}

出力:

TEXT
実行成功
TEXT
# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.orderflow.autoconfigure.OrderFlowAutoConfiguration

6. 自動設定のデバッグとトラブルシューティング

(1) --debugモード

起動時に--debugパラメータを追加すると, Spring Bootは自動設定レポートを出力します。

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

(1) ▶ サンプル:自動設定レポートの読み方

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

出力:

TEXT
実行成功
レポート領域 意味
Positive matches 条件を満たし有効な自動設定
Negative matches 条件を満たさず無効な自動設定
Exclusions 明示的に除外された自動設定
Unconditional classes 無条件で登録される自動設定

(2) 自動設定の除外

(2) ▶ サンプル:不要な自動設定の除外

JAVA
// 方法1:アノテーションによる除外
@SpringBootApplication(exclude = {
    DataSourceAutoConfiguration.class,
    HibernateJpaAutoConfiguration.class
})
public class OrderFlowApplication { ... }

// 方法2:設定プロパティ
// application.yml
spring:
  autoconfigure:
    exclude:
      - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

出力:

TEXT
// 実行成功
除外方法 適用シナリオ 柔軟性
@SpringBootApplication(exclude) 常に除外する場合 コンパイル時に決定
spring.autoconfigure.exclude 環境ごとに除外する場合 実行時に変更可能
@ConditionalOnProperty 条件で除外する場合 最も柔軟

7. 総合サンプル:OrderFlow通知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) {
        // メール送信ロジック
        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

❓ よくある質問

Q 自動設定と手動設定は競合しますか?
A しません。自動設定クラスは@ConditionalOnMissingBeanを多用しており, 同じ型のBeanを手動で定義すると, 自動設定は自動的に譲ります。これが「ユーザー定義優先」の原則です。
Q 自動設定が有効にならないのはなぜですか?
A よくある原因:1)依存クラスがクラスパスに欠落している;2)@ConditionalOnPropertyの条件を満たしていない;3)AutoConfiguration.importsファイルのパスまたは内容が正しくない;4)自動設定クラスがコンポーネントスキャンの範囲外 (ただし自動設定はimportsファイル経由で読み込まれるためスキャン不要)。
Q spring.factoriesは引き続き使用できますか?
A Spring Boot 3.xは後方互換性のためspring.factoriesをサポートしていますが, AutoConfiguration.importsファイルの使用を優先してください。spring.factoriesは将来のバージョンで削除される予定です。
Q カスタムStarterにはいくつのモジュールが必要ですか?
A 通常2つ:1)autoconfigureモジュール (自動設定コード);2)starterモジュール (依存関係を集約するpom.xml)。シンプルなプロジェクトでは1つのモジュールにまとめることもできます。
Q 現在有効な自動設定を確認するにはどうすればよいですか?
A 1)--debugパラメータで起動してレポートを確認;2)Actuatorの/actuator/conditionsエンドポイントを確認;3)IDEでAutoConfiguration.importsファイルを検索。
Q 自動設定を除外するリスクは何ですか?
A 除外すると関連機能が利用不可になり, それに依存する他の自動設定も失敗する可能性があります。除外の影響を理解した上で実行し, デバッグレポートで依存チェーンを確認してください。

📖 まとめ


📝 練習問題

  1. 基本問題 (難易度 ⭐):--debugモードでOrderFlowプロジェクトを起動し, "Positive matches"の自動設定クラスをすべてリストアップし, 各自動設定に必要なクラスパス条件を理解してください。

  2. 応用問題 (難易度 ⭐⭐):orderflow-spring-boot-starterを作成し, @ConditionalOnPropertyスイッチで制御される通知機能を含めてください。OrderFlowプロジェクトに統合してテストしてください。

  3. チャレンジ問題 (難易度 ⭐⭐⭐):複数実装をサポートする自動設定システムを実装してください。クラスパスにKafkaがあればKafka通知, なければメール通知, どちらもなければログ通知を使用する仕組みにしてください。条件アノテーションの優先度と排他設計について考察してください。

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%