1
2

More than 1 year has passed since last update.

Springで自動生成されるBean名をFQCNに変更する方法

Last updated at Posted at 2022-02-01

はじめに

デフォルトBean名をFQCNにするための方法について解説します。すでに同様の内容を解説したページがいくつかありますが、独自のBeanNameGenerator実装クラスを定義する内容のものが多く、標準で用意されているBeanNameGenerator実装クラスを利用する例や複数の設定方法を網羅している解説は無かったため、備忘録として残しておきます。

概要

SpringでアノテーションベースのBean定義を行う場合、特にBean名を明示しない限り、暗黙的にクラス名をLower Camel CaseにしたものがBean名として与えられます。パッケージ名は無視されてしまうので、状況によってはBean名が重複しConflictingBeanDefinitionExceptionが発生してしまうことがあります。

package com.example.demo.package1
@Service
public class UserService {
	/* Bean名:userService */
}
package com.example.demo.package2
@Service
public class UserService {
	/* Bean名:userService */
}

クラス名を変更したり、アノテーションにBean名を渡したりすれば回避できますが、クラス数が多いとその管理も面倒になります。

package com.example.demo.package1
@Service("userService1")
public class UserService {
	/* Bean名:userService1 */
}
package com.example.demo.package2
@Service("userService2")
public class UserService {
	/* Bean名:userService2 */
}

デフォルトで与えられるBean名をパッケージ名まで含めたFQCNにすることで、この問題を回避することができます。

BeanNameGeneratorの指定

Springのコンポーネントスキャン時に使用されるBeanNameGeneratorインターフェースの実装クラスをFullyQualifiedAnnotationBeanNameGeneratorクラスに変更することで、デフォルトで与えられるBean名をFQCNに変更することができます。
BeanNameGeneratorインターフェースは、コンポーネントスキャン時にBean名を自動生成するために使われるインターフェースで、Bean名の生成ロジックはその実装クラスに依存します。デフォルトで使用される実装クラスはAnnotationBeanNameGeneratorクラスです。
コンポーネントスキャン時に使用されるBeanNameGenerator実装クラスを指定する方法はいくつか存在します。

FullyQualifiedAnnotationBeanNameGeneratorクラスはSpring Framework 5.2.3 (Spring Boot 2.2.3)で追加されたため、それ以前のバージョンを使用する場合はこちらの記事等を参考に、独自のBeanNameGenerator実装クラスを定義して使用してください。

@​SpringBootApplication で指定する

SpringBootを使用している場合には、メインクラスに付与する@SpringBootApplicationアノテーションのnameGeneratorパラメータにBeanNameGenerator実装クラスを指定することで、コンポーネントスキャン時にその実装クラスが使用されるようになります。

@SpringBootApplication(nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class)
public class DemoApplication {
	/*...*/
}

@​ComponentScan で指定する

SpringBootを使用せず、JavaベースでBean定義を行っている場合は、@ComponentScanアノテーションのnameGeneratorパラメータにBeanNameGenerator実装クラスを指定することで、コンポーネントスキャン時にその実装クラスが使用されるようになります。

@Configuration
@ComponentScan(basePackages = "com.example.demo", 
		nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class)
public class AppConfig {
	/*...*/
}

XMLで指定する

SpringBootを使用せず、XMLベースでBean定義を行っている場合は、<context:component-scan>タグのnameGenerator属性にBeanNameGenerator実装クラスのFQCNを指定することで、コンポーネントスキャン時にその実装クラスが使用されるようになります。

<context:component-scan
        base-package="com.example.demo"
        name-generator="org.springframework.context.annotation.FullyQualifiedAnnotationBeanNameGenerator" />

MyBatis を使用する場合

MyBatisのMapperクラスなどのように、Springのコンポーネントスキャン以外の方法でBean登録されるBeanについては、前述の設定とは別の設定が必要になることがあります。
MyBatisでは、以下の方法でMapperクラスのデフォルトBean名の生成に使用されるBeanNameGenerator実装クラスを指定することができます。

@​MapperScan で指定する

SpringBootを使用している場合や、JavaベースでBean定義を行っている場合は、@MapperScanアノテーションのnameGeneratorパラメータにBeanNameGenerator実装クラスを指定することで、マッパースキャン時にその実装クラスが使用されるようになります。

@SpringBootApplication(nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class)
@MapperScan(nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class)
public class DemoApplication {
	/*...*/
}

XMLで指定する

SpringBootを使用せず、XMLベースでBean定義を行っている場合は、<mybatis:scan>タグのnameGenerator属性にBeanNameGenerator実装クラスのFQCNを指定することで、マッパースキャン時にその実装クラスが使用されるようになります。

<mybatis:scan
        base-package="com.example.demo"
        name-generator="org.springframework.context.annotation.FullyQualifiedAnnotationBeanNameGenerator" />

参考

ご意見・ご指摘等あればコメントいただけると幸いです。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2