excluir @Component de @ComponentScan

votos
46

Eu tenho um componente que eu quero excluir de uma @ComponentScanem uma determinada @Configuration:

@Component(foo) class Foo {
...
}

Caso contrário, parece colidir com alguma outra classe no meu projeto. Eu não entender completamente a colisão, mas se eu comente a @Componentanotação, as coisas funcionam como eu quero que eles. Mas outros projetos que contam com esta biblioteca esperar desta classe a ser gerido pela Spring, então eu quero ignorá-lo apenas em meu projeto.

Eu tentei usar @ComponentScan.Filter:

@Configuration 
@EnableSpringConfigured
@ComponentScan(basePackages = {com.example}, excludeFilters={
  @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}

mas ele não aparece para trabalhar. Se eu tentar usar FilterType.ASSIGNABLE_TYPE, eu recebo um erro estranho sobre ser incapaz de carregar alguma classe aparentemente aleatória:

Causada por: java.io.FileNotFoundException: recurso caminho de classe [junit / framework / TestCase.class] não pode ser aberto porque ele não existe

Eu também tentei usar type=FilterType.CUSTOMda seguinte forma:

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

Mas isso não parece excluir o componente da verificação como eu quero.

Como faço para excluí-lo?

Publicado 24/09/2013 em 23:03
fonte usuário
Em outras línguas...                            


7 respostas

votos
53

A configuração parece tudo bem, exceto que você deve usar excludeFiltersem vez de excludes:

@Configuration @EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
  @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}
Respondeu 24/09/2013 em 23:39
fonte usuário

votos
14

Outra abordagem é a utilização de novas anotações condicionais. Desde simples Spring 4 você pode usar anotação @Conditional:

@Component("foo")
@Conditional(FooCondition.class)
class Foo {
    ...
}

e definir a lógica condicional para registrar componente Foo:

public class FooCondition implements Condition{
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // return [your conditional logic]
    }     
}

lógica condicional pode ser baseada em contexto, porque você tem acesso a fábrica de feijão. Por exemplo, quando componente "Bar" não está registrado como bean:

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

Com Primavera de inicialização (deve ser usado para cada novo projeto Primavera), você pode usar essas anotações condicionais:

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

Você pode evitar a criação classe de condição desta forma. Consulte a documentação da Primavera de arranque para mais detalhes.

Respondeu 06/12/2014 em 16:11
fonte usuário

votos
30

Usando tipos explícitos em filtros de varredura é feio para mim. Acredito abordagem mais elegante é criar próprio anotação do marcador:

public @interface IgnoreDuringScan {
}

componente marca que deve ser excluído com ele:

@Component("foo") 
@IgnoreDuringScan
class Foo {
    ...
}

E excluir esta anotação da sua digitalização componente:

@ComponentScan(excludeFilters = @Filter(IgnoreDuringScan.class))
public class MySpringConfiguration {}
Respondeu 07/12/2014 em 16:06
fonte usuário

votos
1

No caso do componente excluindo teste ou configuração de teste, da mola de arranque 1,4 introduzidos novos anotações de teste @TestComponente@TestConfiguration .

Respondeu 06/12/2016 em 10:36
fonte usuário

votos
3

No caso de você precisa definir dois ou mais excludeFilters critérios, você tem que usar a matriz.

Para instâncias nesta seção do código que deseja excluir todas as classes no org.xxx.yyy pacote e outra específica classe, MyClassToExclude

 @ComponentScan(            
        excludeFilters = {
                @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.xxx.yyy.*"),
                @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = MyClassToExclude.class) })
Respondeu 22/06/2017 em 14:30
fonte usuário

votos
1

Tive um problema quando se utiliza @Configuration , @EnableAutoConfiguration e @ComponentScan ao tentar excluir classes de configuração específicas, a coisa é que não funcionou!

Finalmente, I resolveu o problema usando @SpringBootApplication , que de acordo com a documentação da mola faz a mesma funcionalidade como o acima três em uma anotação.

Outra dica é tentar primeiro sem refinar sua varredura do pacote (sem o filtro basePackages).

@SpringBootApplication(exclude= {Foo.class})
public class MySpringConfiguration {}
Respondeu 09/07/2017 em 14:54
fonte usuário

votos
0

Eu precisava de excluir uma auditoria @Aspect @Component do contexto aplicativo, mas apenas para algumas classes de teste. Acabei usando @profile ( "Auditoria") na classe aspecto; incluindo o perfil para operações normais, mas excluindo-lo (não colocá-lo em @ActiveProfiles) nas classes de testes específicos.

Respondeu 12/07/2018 em 05:10
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more