@Primaryの使い方と引数を徹底解説!【初心者向け】

こんにちは!今回は、Spring Frameworkで複数のBeanが存在する場合に優先的に使用されるアノテーション、@Primaryについて詳しく解説します。@Primaryを使えば、依存関係の注入時にどのBeanを優先的に使用するかを指定でき、アプリケーションの柔軟性を向上させることができます。

Beanについて

@Primaryとは?

@Primaryとは、

「同じ型の複数のBeanが定義されている場合に、優先的に使用されるBeanを指定するためのアノテーション」

のことです。

通常、Springでは同じ型のBeanが複数存在する場合、どのBeanを使用すればよいか分からなくなり、NoUniqueBeanDefinitionExceptionが発生します。このような場合、@Primaryを使うことで優先するBeanを指定でき、依存関係の注入時にエラーを避けられます。

基本的な使い方

まずは、簡単なコード例を見てみましょう。ここでは、同じインターフェースを実装する複数のクラスの中で、特定のクラスを優先して使用するケースを紹介します。

@Component
public class MyServiceA implements MyService {
    public void execute() {
        System.out.println("Service A");
    }
}

@Component
@Primary
public class MyServiceB implements MyService {
    public void execute() {
        System.out.println("Service B");
    }
}

上記のコードでは、MyServiceインターフェースを2つのクラスMyServiceAMyServiceBが実装しています。MyServiceBには@Primaryアノテーションが付いているため、SpringはMyService型の依存関係が必要なとき、MyServiceBを優先してインジェクションします。

@Autowiredと併用

@Primaryは通常、@Autowiredと併用して使われます。@Autowiredで複数の候補がある場合、@Primaryが付与されたBeanが自動的に選択されます。

@Service
public class MyController {
    private final MyService myService;

    @Autowired
    public MyController(MyService myService) {
        this.myService = myService;
    }

    public void perform() {
        myService.execute();
    }
}

この例では、MyServiceのインスタンスとしてMyServiceBが注入され、「Service B」が出力されます。

応用例:特定のコンフィグレーションで使用

@Primaryは、特定の条件下で使用するためにBeanの優先順位を制御することも可能です。たとえば、開発環境と本番環境で異なる実装を使用したい場合、@Primaryを使うことで環境ごとに注入されるBeanを切り替えられます。

@Configuration
public class AppConfig {

    @Bean
    public MyService myServiceA() {
        return new MyServiceA();
    }

    @Bean
    @Primary
    public MyService myServiceB() {
        return new MyServiceB();
    }
}

この場合、myServiceBが@Primaryで優先されますが、特定の条件でmyServiceAを使いたい場合には、@Qualifierアノテーションを併用することができます。

@Primary vs @Qualifier

@PrimaryはBeanの優先順位を設定する方法ですが、すべてのケースで使えるわけではありません。例えば、明示的に特定のBeanを指定したい場合は、@Qualifierを使用するのが一般的です。@Qualifierを使えば、複数のBeanが存在しても名前で特定のBeanを選択できます。

@Autowired
@Qualifier("myServiceA")
private MyService myService;

この例では、@Primaryが設定されていても、myServiceAという特定のBeanが選ばれます。

違いのまとめ

  • @Primary
    • デフォルトのBeanを指定するために使用。
    • 明示的に指定がない場合に優先される。
    • コンテナ内に同じ型のBeanが複数あるときに、どれを自動で注入するか決める。
  • @Qualifier
    • Beanを明示的に選択するために使用。
    • 名前を使ってどのBeanを注入するか指定する。
    • @Primaryが付いているBeanがあっても、@Qualifierで指定した方が優先される。

@Primaryの使い方【応用編】

@Primaryは、プロジェクトの規模が大きくなると、複数の異なる実装を持つBeanを管理するために非常に役立ちます。以下に、少し高度な使い方を見ていきましょう。

1. カスタム条件に基づくBeanの選択

複数のコンフィグレーションクラスで異なるBeanを定義している場合、@Primaryを使って特定の条件に基づいて優先されるBeanを選択することができます。

@Configuration
public class DevConfig {

    @Bean
    @Primary
    public MyService devService() {
        return new MyServiceA();
    }
}

@Configuration
public class ProdConfig {

    @Bean
    public MyService prodService() {
        return new MyServiceB();
    }
}

ここでは、開発環境(DevConfig)ではMyServiceAが優先され、本番環境(ProdConfig)では明示的にMyServiceBを選択するようにできます。

2. テストケースでの使用

テストケースにおいて、@Primaryを使うことでモックやテスト用のBeanを優先的に注入できます。

@TestConfiguration
public class TestConfig {

    @Bean
    @Primary
    public MyService mockService() {
        return mock(MyService.class);
    }
}

このように、テスト環境ではモックのBeanを優先させることができ、依存関係を簡単に制御できます。

@Primaryの引数

@Primary自体は特別な引数を持たず、シンプルにBeanの優先順位を決定するために使用されます。@Primaryが付与されたBeanは、他のBeanよりも優先的に注入されるため、@Autowiredや他の依存関係注入メカニズムと併用されることが多いです。

おわりに

@Primaryを使えば、Spring FrameworkでのBean管理をより柔軟に行うことができ、依存関係の注入時にエラーを回避することができます。今回は基本的な使い方から応用例まで紹介しましたので、ぜひ実際のプロジェクトで試してみてください!

もっと詳しく知りたい方は、Spring公式ドキュメントを見てみてくださいね。

他の記事が見たい方はこちら!↓↓↓

タイトルとURLをコピーしました