Springコンポーネントのスキャン

1。概要

このチュートリアルでは、Springでのコンポーネントスキャンについて説明します。Springを使用する場合、クラスに注釈を付けてSpringBeanにすることができます。ただし、この特定の実行ではすべてのクラスがBeanになる必要はないためそれに加えて、これらの注釈付きクラスを検索する場所をSpringに指示できます

もちろん、コンポーネントスキャンにはいくつかのデフォルトがありますが、検索用にパッケージをカスタマイズすることもできます。

まず、デフォルト設定を見てみましょう。

2.引数なしの@ComponentScan

2.1。Springアプリケーションでの@ComponentScanの使用

Springでは@ ComponentScanアノテーションと@Configurationアノテーションを使用して、スキャンするパッケージを指定します。引数なしの@ComponentScanは、現在のパッケージとそのすべてのサブパッケージをスキャンするようにSpringに指示します。

我々は以下の持っていると言う@Configurationcom.baeldung.componentscan.springappのパッケージを:

@Configuration @ComponentScan public class SpringComponentScanApp { private static ApplicationContext applicationContext; @Bean public ExampleBean exampleBean() { return new ExampleBean(); } public static void main(String[] args) { applicationContext = new AnnotationConfigApplicationContext(SpringComponentScanApp.class); for (String beanName : applicationContext.getBeanDefinitionNames()) { System.out.println(beanName); } } }

また、com.baeldung.componentscan.springapp.animalsパッケージにCatコンポーネントとDogコンポーネントがあるとします。

package com.baeldung.componentscan.springapp.animals; // ... @Component public class Cat {}
package com.baeldung.componentscan.springapp.animals; // ... @Component public class Dog {}

そして最後に、com.baeldung.componentscan.springapp.flowersパッケージにRoseコンポーネントがあります。

package com.baeldung.componentscan.springapp.flowers; // ... @Component public class Rose {}

main()メソッドの出力には、com.baeldung.componentscan.springappパッケージとそのサブパッケージのすべてのBeanが含まれます。

springComponentScanApp cat dog rose exampleBean

メインアプリケーションクラスは、それがで注釈さだとしてもBeanであることを注意@Configuration、ある@Component

また、メインアプリケーションクラスと構成クラスは必ずしも同じではないことに注意してください。それらが異なる場合は、メインアプリケーションクラスをどこに配置するかは問題ではありません。コンポーネントのスキャンはデフォルトでパッケージから開始されるため、構成クラスの場所のみが重要です

最後に、この例では、@ ComponentScanと同等であることに注意してください。

@ComponentScan(basePackages = "com.baeldung.componentscan.springapp")

ここで、basePackages引数は、スキャン用のパッケージまたはパッケージの配列です。

2.2。SpringBootアプリケーションでの@ComponentScanの使用

Spring Bootの秘訣は、多くのことが暗黙のうちに発生することです。@SpringBootApplicationアノテーションを使用しますが、これは3つのアノテーションの組み合わせにすぎません。

@Configuration @EnableAutoConfiguration @ComponentScan

com.baeldung.componentscan.springbootappパッケージで同様の構造を作成しましょう。今回のメインアプリケーションは次のとおりです。

package com.baeldung.componentscan.springbootapp; // ... @SpringBootApplication public class SpringBootComponentScanApp { private static ApplicationContext applicationContext; @Bean public ExampleBean exampleBean() { return new ExampleBean(); } public static void main(String[] args) { applicationContext = SpringApplication.run(SpringBootComponentScanApp.class, args); checkBeansPresence( "cat", "dog", "rose", "exampleBean", "springBootComponentScanApp"); } private static void checkBeansPresence(String... beans) { for (String beanName : beans) { System.out.println("Is " + beanName + " in ApplicationContext: " + applicationContext.containsBean(beanName)); } } }

他のすべてのパッケージとクラスは同じままです。近くのcom.baeldung.componentscan.springbootappパッケージにコピーするだけです。

Spring Bootは、前の例と同様にパッケージをスキャンします。出力を確認しましょう:

Is cat in ApplicationContext: true Is dog in ApplicationContext: true Is rose in ApplicationContext: true Is exampleBean in ApplicationContext: true Is springBootComponentScanApp in ApplicationContext: true

(すべてのBeanを出力するのではなく)2番目の例でBeanの存在を確認しているだけの理由は、出力が大きすぎるためです。

これは、Spring Bootがpom.xmlファイルの依存関係に依存して、多くのBeanを自動的に作成する暗黙の@EnableAutoConfigurationアノテーションが原因です。

3.引数付きの@ComponentScan

それでは、スキャンのパスをカスタマイズしましょう。たとえば、ローズビーンを除外したいとします。

3.1。特定のパッケージの@ComponentScan

私たちはいくつかの方法でそれを行うことができます。まず、基本パッケージを変更できます。

@ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals") @Configuration public class SpringComponentScanApp {   // ... }

これで、出力は次のようになります。

springComponentScanApp cat dog exampleBean

この背後にあるものを見てみましょう:

  • springComponentScanAppは、AnnotationConfigApplicationContextに引数として渡される構成であるため作成されます
  • exampleBeanは、構成内で構成されたBeanです。
  • は指定されたcom.baeldung.componentscan.springapp.animalsパッケージに含まれています

上記のすべてのカスタマイズは、SpringBootにも適用できます。@ComponentScan@SpringBootApplicationと一緒に使用すると、結果は同じになります。

@SpringBootApplication @ComponentScan(basePackages = "com.baeldung.componentscan.springbootapp.animals")

3.2。除外のある@ComponentScan

もう1つの方法は、フィルターを使用して、除外するクラスのパターンを指定することです。

@ComponentScan(excludeFilters = @ComponentScan.Filter(type=FilterType.REGEX, pattern="com\\.baeldung\\.componentscan\\.springapp\\.flowers\\..*"))

アノテーションはスキャンされたクラスをフィルタリングするためのいくつかの柔軟なオプションをサポートしているため、別のフィルタータイプを選択することもできます。

@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Rose.class))

4.デフォルトパッケージ

@Configurationクラスをデフォルトパッケージに入れないようにする必要があります(つまり、パッケージをまったく指定しないことによって)。この場合、Springはクラスパス内のすべてのjar内のすべてのクラスをスキャンします。これによりエラーが発生し、アプリケーションが起動しない可能性があります。

5。結論

この記事では、Springがデフォルトでスキャンするパッケージと、これらのパスをカスタマイズする方法について学習しました。

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