web-dev-qa-db-ja.com

Spring boot ComponentScan excludeFIlters not exclude

私はSimpleTestを持っています:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SimpleTestConfig.class)
public class SimpleTest {
    @Test
    public void test() {
        assertThat(true);
    }
}

このテストのconfiguration

@SpringBootApplication
@ComponentScan(basePackageClasses = {
        SimpleTestConfig.class,
        Application.class
},
        excludeFilters = @ComponentScan.Filter(
                type = FilterType.ASSIGNABLE_TYPE,
                classes = Starter.class))
public class SimpleTestConfig {
}

Starterクラスを除外しようとしています

package application.starters;

import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;

@Component
public class Starter {
    @PostConstruct
    public void init(){
        System.out.println("initializing");
    }
}

Applicationクラスは次のようになります。

package application;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import static org.springframework.boot.SpringApplication.run;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        run(Application.class, args);
    }
}

しかし、非常に奇妙な理由で、Starterクラスはまだ初期化されています。

誰がComponentScan excludeFiltersStarterクラスを除外していませんか?

11
Daniel Taub

各コンポーネントスキャンは個別にフィルタリングを行います。 SimpleTestConfigからStarter.classを除外すると、SimpleTestConfigApplicationを初期化します。これは、Starterを除外せずに独自の@ComponentScanを実行します。 ComponentScanを使用するクリーンな方法は、各ComponentScanが個別のパッケージをスキャンすることです。その方法で、各フィルターは正常に機能します。 2つの別々のComponentScanが(テストのように)同じパッケージをスキャンするとき、これは機能しません。

これをだます方法の1つは、疑似変数Starterを提供することです。

import org.springframework.boot.test.mock.mockito.MockBean;

public class SimpleTest {
    @MockBean
    private Starter myTestBean;
    ...
}

Springは実際のクラスの代わりにそのモックを使用するため、@PostConstructメソッドは呼び出されません。

その他の一般的なソリューション:

  • 単体テストでApplication.classを直接使用しないでください
  • Starterクラスで@Profile("!TEST")などのSpringプロファイルと注釈を使用します
  • Starterクラスでスプリングブート@ConditionalOn...注釈を使用します
17
tkruse

除外するカスタムコンポーネントスキャンフィルタを定義できます。

サンプルコードは次のようになります。

@SpringBootApplication()
@ComponentScan(excludeFilters=@Filter(type = FilterType.REGEX, pattern="com.wyn.applications.starter.Starter*"))
public class SimpleTestConfig {

}

これは私のために動作します。

詳細については、こちらをご覧ください ブログ

0
Yogi

@ SpringBootApplication 、Springのドキュメントによると、次の機能を組み合わせたものです:@ Configuration@ EnableAutoConfigurationおよび@ ComponentScan 1つの表記法で。

パッケージスキャンを調整せずに(basePackagesフィルターなしで)最初に試してください。

@SpringBootApplication(exclude= {Foo.class})
public class MySpringConfiguration {}
0
dorony