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]から入手できます。