исключить @Component из @ComponentScan
у меня есть компонент, который я хочу исключить из @ComponentScan
в частности @Configuration
:
@Component("foo") class Foo {
...
}
в противном случае, похоже, это столкновение с каким-то другим классом в моем проекте. Я не полностью понимаю столкновение, но если я прокомментирую @Component
аннотация, все работает так, как я хочу. Но другие проекты, которые полагаются на эту библиотеку, ожидают, что этот класс будет управляться весной, поэтому я хочу пропустить его только в своем проекте.
Я попытался с помощью @ComponentScan.Filter
:
@Configuration
@EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}
но это, похоже, не работает. Если я попытаюсь использовать FilterType.ASSIGNABLE_TYPE
, Я получаю странную ошибку о невозможности загрузить какой-то, казалось бы, случайный класс:
вызвано: java.Ио.FileNotFoundException: ресурс пути к классу [junit / framework / TestCase.class] не может быть открыт, потому что он не существует
Я также попытался с помощью type=FilterType.CUSTOM
следующим образом:
class ExcludeFooFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader,
MetadataReaderFactory metadataReaderFactory) throws IOException {
return metadataReader.getClass() == Foo.class;
}
}
@Configuration @EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}
но это, похоже, не исключает компонент из сканирования как я хочу.
как его исключить?
7 ответов
настройки выглядят хорошо, за исключением того, что вы должны использовать excludeFilters
вместо excludes
:
@Configuration @EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}
использование явных типов в фильтрах сканирования уродливо для меня. Я считаю, что более элегантный подход заключается в создании собственной аннотации маркера:
public @interface IgnoreDuringScan {
}
отметьте компонент, который должен быть исключен с ним:
@Component("foo")
@IgnoreDuringScan
class Foo {
...
}
и исключить эту аннотацию из сканирования компонентов:
@ComponentScan(excludeFilters = @Filter(IgnoreDuringScan.class))
public class MySpringConfiguration {}
другой подход-использовать новые условные аннотации. С простые Spring 4 Вы можете использовать @условную аннотацию:
@Component("foo")
@Conditional(FooCondition.class)
class Foo {
...
}
и определите условную логику для регистрации компонента Foo:
public class FooCondition implements Condition{
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// return [your conditional logic]
}
}
условная логика может быть основана на контексте, потому что у вас есть доступ к фабрике бобов. Например, когда компонент" Bar " не зарегистрирован как bean:
return !context.getBeanFactory().containsBean(Bar.class.getSimpleName());
С ботинком весны (должен быть использован для каждой новой весны project), вы можете использовать следующие условные аннотации:
@ConditionalOnBean
@ConditionalOnClass
@ConditionalOnExpression
@ConditionalOnJava
@ConditionalOnMissingBean
@ConditionalOnMissingClass
@ConditionalOnNotWebApplication
@ConditionalOnProperty
@ConditionalOnResource
@ConditionalOnWebApplication
вы можете избежать создания класса условий таким образом. Дополнительные сведения см. В документах Spring Boot.
в случае, если вам нужно определить два или больше excludeFilters критерии, вы должны использовать массив.
для экземпляров в этом разделе кода я хочу исключить все классы в org.ХХХ.ыыы пакет и другой конкретный класс,MyClassToExclude
@ComponentScan(
excludeFilters = {
@ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.xxx.yyy.*"),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = MyClassToExclude.class) })
У меня была проблема при использовании @Configuration, @EnableAutoConfiguration и @ComponentScan при попытке исключить определенные классы конфигурации, дело в том, что это не сработало!
В конце концов я решил проблему, используя @SpringBootApplication, который в соответствии с документацией Spring выполняет те же функции, что и три выше в одной аннотации.
еще один совет-попробовать сначала без уточнения сканирования пакета (без фильтра basePackages).
@SpringBootApplication(exclude= {Foo.class})
public class MySpringConfiguration {}
в случае исключения тестового компонента или тестовой конфигурации Spring Boot 1.4 представил новые аннотации тестирования @TestComponent
и @TestConfiguration
.
Мне нужно было исключить компонент auditing @Aspect @из контекста приложения, но только для нескольких тестовых классов. Я закончил использование @Profile ("аудит") в классе aspect; включая профиль для обычных операций, но исключая его (не помещайте его в @ActiveProfiles) в определенных тестовых классах.