春の@Primaryアノテーション

Spring @Primaryアノテーション

1. 概要

このクイックチュートリアルでは、フレームワークのバージョン3.0で導入されたSpringの@Primaryアノテーションについて説明します。

簡単に言えば、we use @Primary to give higher preference to a bean when there are multiple beans of the same type.

問題を詳しく説明しましょう。

2. なぜ@Primaryが必要なのですか?

場合によっては、we need to register more than one bean of the same type

この例では、EmployeeタイプのJohnEmployee()およびTonyEmployee()Beanがあります。

@Configuration
public class Config {

    @Bean
    public Employee JohnEmployee() {
        return new Employee("John");
    }

    @Bean
    public Employee TonyEmployee() {
        return new Employee("Tony");
    }
}

Spring throws NoUniqueBeanDefinitionException if we try to run the application

同じタイプのBeanにアクセスするには、通常、@Qualifier(“beanName”)アノテーションを使用します。

@Autowiredとともに注入ポイントで適用します。 この例では、構成フェーズでBeanを選択するため、ここでは@Qualifierを適用できません。 linkをフォローすると、@Qualifierのアノテーションについて詳しく知ることができます。

この問題を解決するために、Springは@Primaryアノテーションを提供しています。

3. @Bean@Primaryを使用する

構成クラスを見てみましょう。

@Configuration
public class Config {

    @Bean
    public Employee JohnEmployee() {
        return new Employee("John");
    }

    @Bean
    @Primary
    public Employee TonyEmployee() {
        return new Employee("Tony");
    }
}

TonyEmployee() Beanを@Primaryでマークします。 Springは、JohnEmployee()よりもTonyEmployee()Beanを優先的に注入します。

それでは、アプリケーションコンテキストを開始し、そこからEmployeeBeanを取得しましょう。

AnnotationConfigApplicationContext context
  = new AnnotationConfigApplicationContext(Config.class);

Employee employee = context.getBean(Employee.class);
System.out.println(employee);

アプリケーションを実行した後:

Employee{name='Tony'}

From the output, we can see that the TonyEmployee() instance has a preference while autowiring

4. @Component@Primaryを使用する

We can use @Primary directly on the beans。 次のシナリオを見てみましょう。

public interface Manager {
    String getManagerName();
}

Managerインターフェースと2つのサブクラスBean、DepartmentManagerがあります。

@Component
public class DepartmentManager implements Manager {
    @Override
    public String getManagerName() {
        return "Department manager";
    }
}

そして、GeneralManager Bean:

@Component
@Primary
public class GeneralManager implements Manager {
    @Override
    public String getManagerName() {
        return "General manager";
    }
}

これらは両方とも、ManagerインターフェースのgetManagerName()をオーバーライドします。 また、GeneralManager beanを@Primaryでマークしていることに注意してください。

今回は、@Primary only makes sense when we enable the component scan

@Configuration
@ComponentScan(basePackages="org.example.primary")
public class Config {
}

適切なBeanを見つけながら依存性注入を使用するサービスを作成しましょう。

@Service
public class ManagerService {

    @Autowired
    private Manager manager;

    public Manager getManager() {
        return manager;
    }
}

ここでは、BeanのDepartmentManager GeneralManagerの両方が自動配線の対象になります。

As we marked GeneralManager bean with @Primary, it will be selected for dependency injection

ManagerService service = context.getBean(ManagerService.class);
Manager manager = service.getManager();
System.out.println(manager.getManagerName());

出力は「General manager”.」です。

5. 結論

この記事では、Springの@Primaryアノテーションについて学びました。 コード例を使用して、@Primary.の必要性と使用例を示しました

いつものように、この記事の完全なコードはover on GitHub projectで入手できます。