@ComponentScanアノテーションを使用して複数のパスをスキャンする方法は?


89

Spring 3.1を使用していて、@Configurationand@ComponentScan属性を使用してアプリケーションをブートストラップしています。

実際のスタートは

new AnnotationConfigApplicationContext(MyRootConfigurationClass.class);

この構成クラスには注釈が付けられています

@Configuration
@ComponentScan("com.my.package")
public class MyRootConfigurationClass

これは問題なく動作します。ただし、スキャンするパッケージについてより具体的にしたいので、試してみました。

@Configuration
@ComponentScan("com.my.package.first,com.my.package.second")
public class MyRootConfigurationClass

ただし、これは失敗し、@Component注釈を使用して指定されたコンポーネントが見つからないというエラーが表示されます。

私が求めていることを行う正しい方法は何ですか?

ありがとう


私の知る限り、2つの正解がほぼ同時に出されました。ポイントが少ないからといって、ハゲを受け入れるつもりですが、両方ありがとうございます。
プログラミングガイ

kotlinバージョンで同じことを疑問に思っている場合は、この1つを確認してくださいstackoverflow.com/a/62818187/7747942
Sylhare

回答:


159

@ComponentScanは、次のような文字列配列を使用します。

@ComponentScan({"com.my.package.first","com.my.package.second"})

1つの文字列のみで複数のパッケージ名を指定すると、Springはこれを1つのパッケージ名として解釈するため、見つけることができません。


48

基本パッケージの場所を文字列として指定する代わりにタイプセーフな 別の方法があります。ここAPIを参照してくださいが、以下にも説明しました。

@ComponentScan(basePackageClasses = {ExampleController.class, ExampleModel.class, ExmapleView.class})

クラス参照でbasePackageClasses指定子を使用すると、Springにそれらのパッケージをスキャンするように指示されます(前述の代替方法と同様)が、このメソッドはタイプセーフであり、将来のリファクタリングのためのIDEサポートを追加します-私の本の大きなプラスです。

APIから読み取ると、Springは、スキャンする各パッケージに、この属性の参照として使用する以外の目的を果たさないno-opマーカークラスまたはインターフェイスを作成することを提案しています。

IMO、私はマーカークラス好きではありませんが(ただし、パッケージ情報クラスとほとんど同じです)、型安全性、IDEサポート、およびこのスキャンに含める必要のある基本パッケージの数を大幅に削減します間違いなく、はるかに優れたオプションです。


@ComponentScan({"com.app"、 "com.controllers"})が機能しないのに、@ ComponentScan(basePackageClasses = {"com.controllers"})がうまく機能する理由を誰かが説明できますか?すべてのクラス名を書くのはつまらないと思います
xaverras 2015年

3
スキャンするパッケージに対して、パッケージ内で1つのクラスを指定するだけで済みます。これはマーカークラスとして知られています。クラスのない階層の上位のパッケージをスキャンする必要がある場合、springは、パッケージスキャンの目的でのみ、そのパッケージで定義されている「スプリングマーカー」インターフェイスまたは最終クラスを使用する手法を提案します。
Prancer 2015年

17

パッケージ名を個別に入力してください。パッケージ名にはが必要String[]です。

これの代わりに:

@ComponentScan("com.my.package.first,com.my.package.second")

これを使って:

@ComponentScan({"com.my.package.first","com.my.package.second"})

10

これを行う別の方法は、basePackagesフィールドを使用することです。これは、ComponentScanアノテーション内のフィールドです。

@ComponentScan(basePackages={"com.firstpackage","com.secondpackage"})

jarファイルからComponentScanアノテーション.classを調べると、文字列の配列を受け取るbasePackagesフィールドが表示されます。

public @interface ComponentScan {
String[] basePackages() default {};
}

または、クラスについて明示的に言及することもできます。クラスの配列を取ります

Class<?>[]  basePackageClasses

4

ComponentScanを使用して、を使用して複数のパッケージをスキャンします

@ComponentScan({"com.my.package.first","com.my.package.second"})


1

この依存関係がpom.xmlに追加されていることを確認してください

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

半時間近くを費やした後のおかげで、この行方不明の依存関係だった
DvixExtract

1

私が使う:

@ComponentScan(basePackages = {"com.package1","com.package2","com.package3", "com.packagen"})

0

@ComponentScansアノテーションを使用することもできます。

@ComponentScans(value = { @ComponentScan("com.my.package.first"),
                          @ComponentScan("com.my.package.second") })

4
あなたの答えに説明を追加することを検討してください
yeya
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.