Вопрос:

Spring boot ComponentScan excludeFlters не исключая

java spring spring-boot spring-test

11520 просмотра

3 ответа

1853 Репутация автора

У меня есть SimpleTest :

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

и конфигурация для этого теста:

@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 excludeFiltersне исключает мой Starterкласс?

Автор: Daniel Taub Источник Размещён: 04.01.2018 08:12

Ответы (3)


0 плюса

470 Репутация автора

@SpringBootApplication , в соответствии с документацией Spring, выполняет объединенную функциональность: @Configuration , @EnableAutoConfiguration и @ComponentScan в одной записи.

Попробуйте сначала без уточнения сканирования вашего пакета (без фильтра basePackages).

@SpringBootApplication(exclude= {Foo.class})
public class MySpringConfiguration {}
Автор: dorony Размещён: 04.01.2018 08:28

13 плюса

5581 Репутация автора

Решение

Каждый компонент сканирования выполняет фильтрацию индивидуально. В то время как вы исключаете Starter.classиз SimpleTestConfig, SimpleTestConfigинициализирует Application, что делает его самостоятельно @ComponentScanбез исключения Starter. Чистый способ использования ComponentScan состоит в том, что каждый ComponentScan сканирует отдельные пакеты, поэтому каждый фильтр работает нормально. Когда 2 отдельных сканирования компонентов сканируют один и тот же пакет (как в ваших тестах), это не работает.

Один из способов обмануть это - создать фиктивный Starterбоб:

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

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

Spring будет использовать этот макет вместо реального класса, поэтому @PostConstructметод не будет вызываться.

Другие распространенные решения:

  • Не используйте напрямую Application.classни в одном модульном тесте
  • Используйте профиль Spring и аннотации, такие как @Profile("!TEST")на Starterклассе
  • Используйте весеннюю @ConditionalOn...аннотацию Boot на Starterклассе
Автор: tkruse Размещён: 07.01.2018 03:40

0 плюса

1189 Репутация автора

Вы можете определить пользовательский компонент фильтра сканирования для его исключения.

Пример кода будет выглядеть так:

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

}

Это работает для меня.

Для дальнейшего чтения зайдите в этот блог .

Автор: Yogi Размещён: 11.01.2018 09:56
Вопросы из категории :
32x32