趣旨
-
@ComponentScanを理解していなくて自分がハマった箇所のメモ。
- ベースパッケージから変更/追加する際に注意すること。
- プロトタイプ作成時に多く起こるのかな。
- ベースパッケージから変更/追加する際に注意すること。
- 結論としては、@ComponentScan を定義したクラスと並列もしくは、上位にあるクラスはスキャンしないという話。
環境
- OS
- Windows10 home (64bit)
- Spring Boot
- 1.4.3
- Java
- 1.8.0_111-b14
事象
例
- ベースパッケージ(規定となるパッケージ)
- com.sample.product
- この下に、apiやdomain、serviceといったパッケージを作成し開発を行っていた。
- Applicationクラス(@ComponentScanもしくは、@SpringBootApplicationを定義したクラス)は、com.sample.productname直下に配置されている。
com.sample.product
com.sample.product
├─api
├─commons
├─dao
├─domain
├─service
└ Application.java
- commonsパッケージに格納されているクラスは、将来的に他のproductでも利用中できる(プロジェクト自体も別管理)できるように、パッケージをproductから切り離すようにリファクタリングを行う。
com.sample
com.sample
├─commons
└─product
├─api
├─dao
├─domain
├─service
└ Application.java
- この時に、Application.javaは「com.sample.product」をベースパッケージとして動作するため、「com.sample.commons」配下のクラスを スキャン対象としない!!!
- これを理解していないと、クラスを発見できずにエラーとなる。
- ここで3時間はまりました。。。
対応方法
- クラスを移動(リファクタリング)する。
com.sample
com.sample
├─commons
├─product
| ├─api
| ├─dao
| ├─domain
| └─service
└ Application.java
-
@ComponentScanにスキャン対象のベースパッケージを設定する。
- 例では@SpringBootApplicationを利用しています。
Application.java(修正前)
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
- 移動と同義
Application.java(修正後1)
@SpringBootApplication(scanBasePackages={"com.sample"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
- 対象のパッケージを追加する。
Application.java(修正後2)
@SpringBootApplication(scanBasePackages={"com.sample.commons", "com.sample.product"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
- クラスごと移動するのが楽だと思う。
- それで対応できない場合は、パッケージをする。