исключить @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.io.FileNotFoundException: путь к классу resource [junit/framework/TestCase.класс] не может быть открыт, потому что он не существует




Я также пробовал использовать 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 {}


но это, похоже, не исключает компонент из сканирования как я хочу.



как мне его исключить?

688   7  

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 {}

другой подход заключается в использовании новых условных аннотаций. Так как простые Весна 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]
    }     
}

условная логика может быть основана на контексте, потому что у вас есть доступ к bean factory. Например, когда компонент " Bar " не зарегистрирован как bean:

    return !context.getBeanFactory().containsBean(Bar.class.getSimpleName());

С ботинком весны (должен быть использован для каждой новой весны проекта), вы можете использовать эти условные Примечания:

  • @ConditionalOnBean
  • @ConditionalOnClass
  • @ConditionalOnExpression
  • @ConditionalOnJava
  • @ConditionalOnMissingBean
  • @ConditionalOnMissingClass
  • @ConditionalOnNotWebApplication
  • @ConditionalOnProperty
  • @ConditionalOnResource
  • @ConditionalOnWebApplication

таким образом можно избежать создания класса условий. См. Spring Boot docs для получения более подробной информации.

в случае, если вам нужно определить два или больше excludeFilters критерии, вы должны использовать массив.

для экземпляров в этом разделе кода я хочу исключить все классы в орг.ХХХ.ыыы пакет и другой конкретный класс,MyClassToExclude

 @ComponentScan(            
        excludeFilters = {
                @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.xxx.yyy.*"),
                @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = MyClassToExclude.class) })

У меня была проблема при использовании @настройки, @EnableAutoConfiguration и @ComponentScan при попытке исключить определенные классы конфигурации, дело в том, что это не сработало!

В конце концов я решил проблему с помощью @SpringBootApplication, который в соответствии с документацией Spring выполняет ту же функциональность, что и три выше в одной аннотации.

еще один совет-попробовать сначала без уточнения сканирования пакета (без фильтра базовых пакетов).

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

в случае исключения тестового компонента или тестовой конфигурации Spring Boot 1.4 представила новые аннотации для тестирования @TestComponent и @TestConfiguration.

Мне нужно было исключить компонент auditing @Aspect @из контекста приложения, но только для нескольких тестовых классов. В итоге я использовал @Profile("аудит") в классе aspect; включая профиль для обычных операций, но исключая его (не помещайте его в @ActiveProfiles) в конкретных тестовых классах.

Comments

    Ничего не найдено.