mcpField
S
spring-boot-dependency-injection

spring-boot-dependency-injection

github.com/giuseppe-trisciuoglio開発3653.8k 回インストール7 週間前に更新
リポジトリ

spring-boot-dependency-injection について

Spring Boot 開発者向けに、コンストラクター注入を基本とする依存性注入と明示的な Bean 構成を扱うスキルです。単体テストと最小限のコンテキストテストで、早期に構成上の問題を検出します。

主な機能

  1. 01必須依存関係のコンストラクター注入
  2. 02オプションの依存先の明示的な処理
  3. 03@Primary と @Qualifier による Bean 選択
  4. 04構成クラスでのオブジェクト配線
  5. 05最小限のコンテキストテストと単体テスト

活用シーン

  1. 01Spring サービスやコンポーネントの作成
  2. 02既存コードのフィールド注入の置き換え
  3. 03同じ型の複数 Bean からの選択
  4. 04本格的な統合前の配線検証

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill spring-boot-dependency-injection

インストール後、Claude Code で/spring-boot-dependency-injectionを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
examples.md
reference.md
spring-official-dependency-injection.md

詳細

Spring Bootの依存性注入

概要

Spring Bootでコンストラクターを優先する依存性注入パターンを提供します。

  • コンストラクター注入による必須の依存先
  • ObjectProvider または何もしないフォールバックによるオプションの依存先
  • @Primary と @Qualifier によるBeanの選択
  • 本格的な統合の前に、最小限のコンテキストテストで検証

使用するタイミング

次のような場合に、このスキルを使用します。

  • 新しい @Service、@Component、@Repository、または @Configuration クラスを作成する
  • レガシーなSpringコードのフィールド注入を置き換える
  • QualifierまたはPrimary Beanを使って、同じ型の複数のBeanを解決する
  • nullに依存した配線を避けながら、オプション機能、アダプター、または統合機能を扱う
  • 循環依存や、脆弱なコンテキスト起動時の失敗を確認する
  • コンストラクターベースの直接的なユニットテストに向けてコードを準備する

手順

1. 必須の依存先とオプションの依存先を分ける

各クラスについて、次を特定します。

  • 正しく動作するために必要な必須の依存先
  • 統合、キャッシュ、通知、または機能フラグによる動作を有効にするオプションの依存先

必須の依存先はコンストラクターに指定します。オプションの依存先には、ObjectProvider、条件付きBean、または何もしない実装など、明示的な方法が必要です。

2. コンストラクター注入をデフォルトにする

アプリケーションサービスやアダプターでは、次のようにします。

  • 必須の依存先をコンストラクター経由で注入する
  • 注入するフィールドを final にする
  • Springを起動せずに、ユニットテストでクラスを直接インスタンス化する

通常はコンストラクターが1つあれば十分で、その場合は @Autowired は不要です。

3. オプションの動作を意図的に解決する

適切な選択肢には次のものがあります。

  • 遅延アクセスが便利な場合の ObjectProvider<T>
  • 配線を設定に応じて変更する場合の @ConditionalOnProperty または @ConditionalOnMissingBean
  • 機能の有効・無効を呼び出し側が意識する必要がない場合の、何もしない実装

実行時の動作が曖昧になる、nullを許容する依存先は避けてください。

4. 必要な場合にのみBean選択用アノテーションを使う

同じ型のBeanが複数ある場合は、次のようにします。

  • デフォルトの実装には @Primary を使う
  • 名前付きのバリエーションには @Qualifier を使う
  • Qualifier名は安定させ、簡単に検索できるようにする

選択ルールが複雑になった場合は、サービス全体に分散させず、専用の設定クラスにまとめます。

5. ビジネスコードではなく設定に配線をまとめる

次の場合は @Configuration と @Bean メソッドを使います。

  • オブジェクトがサードパーティーライブラリから提供される
  • 条件付きの生成ロジックが必要である
  • 環境固有の配線や明示的な組み立てが必要である

ビジネスサービスは、インフラストラクチャの依存先がどのようにインスタンス化されるかを知るべきではありません。

6. 配線を明示的に検証する

新しいサービスまたは設定を作成した後は、次の手順を実施します。

  1. 最小限のコンテキストテストで Beanが読み込まれることを確認します。
    @SpringBootTest
    @ContextConfiguration(classes = UserService.class)
    class UserServiceWiringTest {
        @Autowired UserService userService;
        @Test void serviceIsInstantiated() { assertNotNull(userService); }
    }
    
  2. サービスの動作について、コンストラクターベースのユニットテストを実行します(Springは不要です)。
  3. MVC、JPA、またはメッセージングの統合を検証する必要がある場合に限り、スライステストを追加します。
  4. @SpringBootTest は、コンテナー全体の配線検証に限って使用します。

手順1での失敗は、ビジネスロジックを追加する前に配線の問題があることを示します。

例

例1:コンストラクターを優先するアプリケーションサービス
@Service
public class UserService {

    private final UserRepository userRepository;
    private final EmailSender emailSender;

    public UserService(UserRepository userRepository, EmailSender emailSender) {
        this.userRepository = userRepository;
        this.emailSender = emailSender;
    }

    public User register(UserRegistrationRequest request) {
        User user = userRepository.save(User.from(request));
        emailSender.sendWelcome(user);
        return user;
    }
}

このクラスは、モックを使ったユニットテストで直接簡単にインスタンス化できます。

例2:何もしないフォールバックを使ったオプションの依存先
@Service
public class ReportService {

    private final ReportRepository reportRepository;
    private final NotificationGateway notificationGateway;

    public ReportService(
        ReportRepository reportRepository,
        ObjectProvider<NotificationGateway> notificationGatewayProvider
    ) {
        this.reportRepository = reportRepository;
        this.notificationGateway = notificationGatewayProvider.getIfAvailable(NotificationGateway::noOp);
    }
}

これにより、null の処理をクラスのほかの部分に広げず、オプションの動作を明示できます。

例3:明確な選択ルールを持つ複数のBean
@Configuration
public class PaymentConfiguration {

    @Bean
    @Primary
    PaymentGateway stripeGateway() {
        return new StripePaymentGateway();
    }

    @Bean
    @Qualifier("fallbackGateway")
    PaymentGateway mockGateway() {
        return new MockPaymentGateway();
    }
}

デフォルトの経路には @Primary を使い、特定のバリエーションが必要な場合にのみ @Qualifier を使います。

ベストプラクティス

  • 必須の依存関係には、コンストラクターインジェクションを優先してください。
  • サービスのコンストラクターは小規模に保ってください。クラスに必要なコラボレーターが多すぎる場合は、別の抽象化を導入する設計が適している可能性があります。
  • null 許容のオプション依存関係ではなく、何もしない Bean や条件付き Bean を使用してください。
  • フレームワーク固有の生成ロジックは、設定クラスにまとめてください。
  • まず Spring を使わずにサービスをテストし、その後、コンテナーのテストが有効な場合に限って追加してください。
  • リファクタリングでは、フィールドインジェクションを拡張するのではなく、削除してください。

制約と警告

  • フィールドインジェクションは依存関係を隠し、テストの作成を難しくします。
  • 循環依存は通常、設計上の問題です。@Lazyで解決する配線上の小技ではありません。
  • Qualifier を使いすぎるとコードベースの把握が難しくなるため、より適切な抽象化や明確な設定を優先してください。
  • オプションのコラボレーターがない場合でも、動作が決定的である必要があります。
  • フルコンテキストテストを早い段階で使うと、配線失敗の本当の原因が見えにくくなることがあります。

参考資料

  • references/reference.md
  • references/examples.md
  • references/spring-official-dependency-injection.md

関連するスキル

  • spring-boot-crud-patterns
  • spring-boot-rest-api-standards
  • unit-test-service-layer

コメント