1. 概要

Spring Bean に名前を付けると、同じタイプの実装が複数ある場合に非常に役立ちます。 これは、Beanに一意の名前がない場合、SpringがBeanを注入するのがあいまいになるためです。

Beanの命名を制御することで、ターゲットオブジェクトに注入するBeanをSpringに指示できます。

この記事では、Spring Beanの命名戦略について説明し、1つのタイプのBeanに複数の名前を付ける方法についても説明します。

2. デフォルトのBean命名戦略

Springは、Beanを作成するための複数の注釈を提供します。 これらの注釈はさまざまなレベルで使用できます。 たとえば、Beanクラスにいくつかのアノテーションを配置し、Beanを作成するメソッドに他のアノテーションを配置できます。

まず、Springのデフォルトの命名戦略の実際を見てみましょう。 値なしでアノテーションを指定する場合、SpringはどのようにBeanに名前を付けますか?

2.1. クラスレベルの注釈

クラスレベルで使用されるアノテーションのデフォルトの命名戦略から始めましょう。 Beanに名前を付けるために、 Springはクラス名を使用して、最初の文字を小文字に変換します

例を見てみましょう:

@Service
public class LoggingService {
}

ここで、Springはクラス LoggingService のBeanを作成し、「loggingService」という名前を使用して登録します。

これと同じデフォルトの命名戦略は、 @Component @Service @Controller など、SpringBeanの作成に使用されるすべてのクラスレベルのアノテーションに適用できます。 ]。

2.2. メソッドレベルのアノテーション

Springは、Bean作成のメソッドで使用される@Bean@Qualifierなどのアノテーションを提供します。

@Beanアノテーションのデフォルトの命名戦略を理解するための例を見てみましょう。

@Configuration
public class AuditConfiguration {
    @Bean
    public AuditService audit() {
          return new AuditService();
    }
}

この構成クラスでは、SpringはタイプAuditServiceのBeanを「audit」という名前で登録します。これは、メソッドで@Beanアノテーションを使用する場合 [X178X ]Springはメソッド名をBean名として使用します。

メソッドで@Qualifierアノテーションを使用することもできます。その例を、以下に示します。

3. Beanのカスタム命名

同じSpringコンテキストで同じタイプの複数のBeanを作成する必要がある場合、Beanにカスタム名を付け、それらの名前を使用してそれらを参照できます。

では、SpringBeanにカスタム名を付ける方法を見てみましょう。

@Component("myBean")
public class MyCustomComponent {
}

今回、Springは、「myBean」という名前のMyCustomComponentタイプのBeanを作成します。

Beanに明示的に名前を付けているため、Springはこの名前を使用します。この名前を使用して、Beanを参照またはアクセスできます。

@Component( “myBean”)と同様に、 @Service( “myService”) @Controller( “myController”)などの他の注釈を使用して名前を指定できます。 @Bean( “myCustomBean”)の場合、SpringはそのBeanを指定された名前で登録します。

4. @Beanおよび@Qualifierを使用したBeanの命名

4.1. @Bean値付き

前に見たように、 @Bean アノテーションはメソッドレベルで適用され、デフォルトでは、Springはメソッド名をBean名として使用します。

このデフォルトのBean名は上書きできます— @Beanアノテーションを使用して値を指定できます。

@Configuration
public class MyConfiguration {
    @Bean("beanComponent")
    public MyCustomComponent myComponent() {
        return new MyCustomComponent();
    }
}

この場合、タイプ MyCustomComponent のBeanを取得する場合は、「beanComponent」という名前を使用してこのBeanを参照できます。

Spring @Bean アノテーションは通常、構成クラスのメソッドで宣言されます。 同じクラスの他の@Beanメソッドを直接呼び出すことにより、それらを参照する場合があります。

4.2. @Qualifier値付き

@Qualifierアノテーションを使用してBeanに名前を付けることもできます。

まず、複数のクラスによって実装されるインターフェイスAnimalを作成しましょう。

public interface Animal {
    String name();
}

次に、実装クラス Cat を定義し、それに@Qualifierアノテーションを値「cat」で追加しましょう。

@Component 
@Qualifier("cat") 
public class Cat implements Animal { 
    @Override 
     public String name() { 
        return "Cat"; 
     } 
}

Animal の別の実装を追加し、 @Qualifierと値「dog 」:で注釈を付けましょう。

@Component
@Qualifier("dog")
public class Dog implements Animal {
    @Override
    public String name() {
        return "Dog";
    }
}

それでは、[X23X]Animalの2つの異なるインスタンスを挿入できるクラスPetShowを作成しましょう。

@Service 
public class PetShow { 
    private final Animal dog; 
    private final Animal cat; 

    public PetShow (@Qualifier("dog")Animal dog, @Qualifier("cat")Animal cat) { 
      this.dog = dog; 
      this.cat = cat; 
    }
    public Animal getDog() { 
      return dog; 
    }
    public Animal getCat() { 
      return cat; 
    }
}

クラスPet Showでは、コンストラクターパラメーターに @Qualifier アノテーションを使用して、タイプAnimalの両方の実装を注入しました。 、各アノテーションの値属性に修飾されたBean名が含まれます。 この修飾名を使用するときはいつでも、Springはその修飾名を持つBeanをターゲットBeanに注入します。

5. Bean名の確認

これまで、SpringBeanに名前を付ける方法を示すさまざまな例を見てきました。 問題は、これをどのように検証またはテストできるかということです。

動作を検証するための単体テストを見てみましょう。

@ExtendWith(SpringExtension.class)
public class SpringBeanNamingUnitTest {
    private AnnotationConfigApplicationContext context;
    
    @BeforeEach
    void setUp() {
        context = new AnnotationConfigApplicationContext();
        context.scan("com.baeldung.springbean.naming");
        context.refresh();
    }
    
    @Test
    void givenMultipleImplementationsOfAnimal_whenFieldIsInjectedWithQualifiedName_thenTheSpecificBeanShouldGetInjected() {
        PetShow petShow = (PetShow) context.getBean("petShow");
        assertThat(petShow.getCat().getClass()).isEqualTo(Cat.class);
        assertThat(petShow.getDog().getClass()).isEqualTo(Dog.class);
    }

このJUnitテストでは、Beanの取得に使用されるsetUpメソッドでAnnotationConfigApplicationContextを初期化しています。

次に、標準のアサーションを使用してSpringBeanのクラスを検証するだけです。

6. 結論

この簡単な記事では、デフォルトおよびカスタムのSpringBeanの命名戦略について説明しました。

また、同じタイプの複数のBeanを管理する必要があるユースケースでカスタムSpringBeanの命名がどのように役立つかについても学びました。

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