Springコンポーネントスキャニング
1概要
このチュートリアルでは、Springでのコンポーネントスキャンについて説明します。 Springで作業するときは、クラスをSpring Beanにするためにクラスに注釈を付けることができます。しかし、それ以外にも、これらのアノテーション付きクラスを検索する場所をSpringに指示することができます。** この特定の実行ではすべてがBeanになる必要はないためです。
もちろん、コンポーネントスキャンにはデフォルト値がいくつかありますが、検索用にパッケージをカスタマイズすることもできます。
まず、デフォルト設定を見てみましょう。
2引数なしの
@ ComponentScan
2.1. Springアプリケーションで
@ ComponentScan
を使用する
Springでは、スキャンしたいパッケージを指定するために
@ Configuration
アノテーションとともに
@ ComponentScan
アノテーションを使用します。引数なしの
@ ComponentScan
は、現在のパッケージとそのすべてのサブパッケージをスキャンするようにSpringに指示します。
com.baeldung.componentscan.springapp
パッケージに次の
@ Configuration
があるとします。
@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
メインアプリケーションクラスは、
@ Configuration、つまり
@ Component__でアノテーションが付けられているので、Beanでもあることに注意してください。
また、メインアプリケーションクラスと設定クラスは必ずしも同じではありません。異なる場合は、メインアプリケーションクラスをどこに配置するかは重要ではありません。 ** デフォルトではコンポーネントのスキャンがそのパッケージから開始されるため、構成クラスの場所だけが問題になります。
最後に、この例では
@ ComponentScan
は次のものと同等です。
@ComponentScan(basePackages = "com.baeldung.componentscan.springapp")
basePackages
引数は、スキャン対象のパッケージまたはパッケージの配列です。
2.2. Spring Bootアプリケーションで
@ 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
2番目の例でBeanの存在をチェックしているのは、出力が大きすぎるためです。
これは、Spring Bootが
pom.xmlファイルの依存関係に依存して自動的に多くのBeanを作成するようにする、暗黙の
@ EnableAutoConfiguration__アノテーションのためです。
3
@ ComponentScan
引数付き
それではスキャンのパスをカスタマイズしましょう。たとえば、
Rose
Beanを除外したいとしましょう。
いくつかの方法でそれを行うことができます。まず、基本パッケージを変更します。
@ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals")
@Configuration
public class SpringComponentScanApp {
//...
}
出力は次のようになります。
springComponentScanApp
cat
dog
exampleBean
この背後にあるものを見てみましょう:
-
springComponentScanApp
は、次のように渡された設定であるため作成されます。
AnnotationConfigApplicationContext
への引数
**
exampleBean
は、設定内で設定されたBeanです。
-
cat
と
dog
は指定された中にあります
com.baeldung.componentscan.springapp.animals
パッケージ
もう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))
上記のカスタマイズはすべてSpring Bootにも適用できます。
@ ComponentScan
を
@ SpringBootApplication
と一緒に使用すると、結果は同じになります。
@SpringBootApplication
@ComponentScan(basePackages = "com.baeldung.componentscan.springbootapp.animals")
4デフォルトパッケージ
@ Configuration
クラスhttps://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-structuring-your-code.htmlをデフォルトのパッケージに入れないでパッケージをまったく指定しないことによって)。この場合、Springはクラスパス内のすべてのjar内のすべてのクラスをスキャンします。これはエラーの原因となり、おそらくアプリケーションは起動しません。
5結論
この記事では、Springがデフォルトでスキャンするパッケージと、これらのパスをカスタマイズする方法を学びました。
いつものように、完全なコードはhttps://github.com/eugenp/tutorials/tree/master/spring-boot[over on GitHub]から入手できます。