2014-08-28 15 views
5

Ho una classe che desidero escludere durante la scansione dei componenti. Sto usando il codice qui sotto per farlo, ma che non sembra funzionare, anche se tutto sembra essere di destraComponentScan exclude I filtri non funzionano nella primavera 4.0.6.RELEASE

@ComponentScan(basePackages = { "common", "adapter", "admin"}, excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ServiceImpl.class) }) 

In realtà io voglio avere classe "ServiceImpl", che implementa l'interfaccia "Servizio", viene utilizzato in il mio resto api logico e mentre faccio il test di integrazione di una API voglio escludere questa impiantazione e caricare l'implementazione derisa. Ma questo non sembra accadere in quanto anche dopo aver usato il sopra sto ottenendo l'errore sotto

No qualifying bean of type [admin.Service] is defined: expected single matching bean but found 2: ServiceMockImpl,ServiceImpl 

ho speso troppo tempo su questo, ma nulla funziona.

Qualsiasi aiuto è apprezzato.

risposta

21

Dopo molte ricerche e ricerche ho notato che il comportamento di Spring è un po 'strano in termini di scansione dei componenti.

artefatti erano come questo:

"ServiceImpl" è la vera classe di implementazione che implementa l'interfaccia "Servizio". "ServiceMockImpl" è la classe di impianto derisa che implementa l'interfaccia "Servizio".

Volevo modificare la scansione dei componenti in modo che carichi solo "ServiceMockImpl" ma non "ServiceImpl".

Ho dovuto aggiungere "@ ComponentScan.Filter (type = FilterType.ASSIGNABLE_TYPE, value = ServiceImpl.class)", nel "@ComponentScan" della classe di configurazione di test, per escludere quella particolare classe dalla scansione dei componenti. Ma entrambe le classi venivano caricate anche dopo aver apportato le modifiche sopra indicate e i test stavano fallendo.

Dopo un sacco di lavoro e ricerche ho scoperto che il "ServiceImpl" si stava caricando a causa dell'altra classe che stava per essere caricata e ha "@ComponentScan" per tutti i pacchetti sopra. Così ho aggiunto il codice per escludere la classe "Application" dalla scansione del componente come segue "@ ComponentScan.Filter (type = FilterType.ASSIGNABLE_TYPE, value = Application.class)".

Dopo che ha funzionato come previsto.

codice come qui di seguito

@ComponentScan(excludeFilters = { 
    @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = OAuthCacheServiceImpl.class), 
    @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Application.class) }, basePackages = { 
    "common", "adapter", "admin"}) 

ho visto che molte domande sulla scansione dei componenti sono senza risposta per molto tempo quindi ho pensato di aggiungere questi dettagli in quanto può aiutare qualcuno in futuro.

HTH ...

+0

Grazie! aiuta! – zhuguowei

+2

Ottima idea! Questo è ciò che funziona anche per me: '@ComponentScan (basePackages =" org.package ", excludeFilters = @Filter (classes = {Controller.class, Configuration.class}))' Sembra che dobbiamo dire esplicitamente a Spring saltare le classi di configurazione. – Yuriy

1

In un primo momento, Grazie mille per le risposte di @Yuriy e @ ripudam, ma ciò che mi rende confuso è quando i miei excludeFilters contiene Configuration.class devo usare @import per importare il Classe che annotato da @ Configuration.Io trovato quando uso excludeFilters = {@Filter (type = FilterType.ANNOTATION, value {EnableWebMvc.class, Controller.class}), tutto funziona bene.Il ContextLoaderListener non registra il Controller in un primo momento .

Per esempio

//@Import(value = { SecurityConfig.class, MethodSecurityConfig.class, RedisCacheConfig.class, QuartzConfig.class }) 
@ComponentScan(basePackages = { "cn.myself" }, excludeFilters = { 
     @Filter(type = FilterType.ANNOTATION,value={EnableWebMvc.class,Controller.class}) }) 
public class RootConfig { 
} 
0

ho avuto un problema quando si utilizza @Configuration, @EnableAutoConfiguration e @ComponentScan durante il tentativo di escludere le classi di configurazione specifiche, la cosa è non ha funzionato!

Alla fine ho risolto il problema utilizzando @SpringBootApplication, che in base alla documentazione di Spring ha la stessa funzionalità dei tre precedenti in un'annotazione.

Un altro consiglio è di provare prima senza perfezionare la scansione del pacchetto (senza il filtro basePackages).

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