webentwicklung-frage-antwort-db.com.de

ComponentScan excludeFilters funktioniert im Frühjahr nicht 4.0.6.RELEASE

Ich habe eine Klasse, die ich beim Scannen von Komponenten ausschließen möchte. Ich benutze den folgenden Code, um das zu tun, aber das scheint nicht zu funktionieren, obwohl alles richtig zu sein scheint

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

Eigentlich möchte ich, dass die Klasse "ServiceImpl", die die Schnittstelle "Service" implementiert, in meiner restlichen API-Logik verwendet wird. Während des Integrationstests einer API möchte ich diese Implementierung ausschließen und die verspottete Implementierung laden. Dies scheint jedoch nicht zu passieren, da ich auch nach der Verwendung des obigen Befehls den folgenden Fehler erhalte

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

Ich habe zu viel Zeit damit verbracht, aber nichts funktioniert.

Jede Hilfe wird geschätzt.

11
Ripu Daman

Nach viel Arbeit und Recherche habe ich festgestellt, dass Spring beim Scannen von Bauteilen ein wenig seltsames Verhalten zeigt.

Artefakte waren wie folgt:

"ServiceImpl" ist die eigentliche Implementierungsklasse, die die Schnittstelle "Service" implementiert. "ServiceMockImpl" ist die verspottete Implantationsklasse, die die "Service" -Schnittstelle implementiert.

Ich wollte das Scannen von Komponenten optimieren, damit nur "ServiceMockImpl" geladen wird, nicht jedoch "ServiceImpl".

Ich musste den "@ ComponentScan.Filter (type = FilterType.ASSIGNABLE_TYPE, value = ServiceImpl.class)" im "@ComponentScan" der Testkonfigurationsklasse hinzufügen, um diese bestimmte Klasse vom Komponentenscan auszuschließen. Aber beide Klassen wurden geladen, obwohl die obigen Änderungen vorgenommen wurden und die Tests fehlgeschlagen sind.

Nach viel Arbeit und Recherche stellte ich fest, dass "ServiceImpl" aufgrund der anderen Klasse geladen wurde, die geladen wurde und "@ComponentScan" für alle Pakete enthält. So habe ich den Code zum Ausschließen der Klasse "Application" vom Komponentenscan wie folgt hinzugefügt: "@ ComponentScan.Filter (type = FilterType.ASSIGNABLE_TYPE, value = Application.class)".

Danach hat es wie erwartet funktioniert.

Code wie unten

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

Ich habe gesehen, dass viele Fragen zum Scannen von Komponenten lange Zeit unbeantwortet sind, daher habe ich mir überlegt, diese Details hinzuzufügen, da dies möglicherweise jemandem in Zukunft helfen wird.

HTH ...

30
Ripu Daman

Zunächst vielen Dank für die Antworten von @Yuriy und @ ripudam, aber was mich verwirrt, ist, dass mein excludeFilters Configuration.class enthält. Ich muss @Import verwenden, um die Klasse zu importieren, die von @ Configuration.I gefunden wurde, wenn ich sie verwende excludeFilters = {@Filter (type = FilterType.ANNOTATION, value {EnableWebMvc.class, Controller.class}), alles funktioniert gut. Der ContextLoaderListener registriert den Controller zuerst nicht.

Zum Beispiel

//@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 {
}
1
Forest10

Ich hatte ein Problem bei der Verwendung von @Configuration , @EnableAutoConfiguration und @ComponentScan beim Versuch, bestimmte Konfigurationsklassen auszuschließen, das Problem ist, dass es nicht funktioniert hat!

Schließlich löste ich das Problem mit @SpringBootApplication , das laut Spring-Dokumentation dieselbe Funktionalität wie die drei oben genannten in einer Anmerkung ausführt.

Ein weiterer Tipp ist, zuerst zu versuchen, ohne den Paketscan zu verfeinern (ohne den basePackages-Filter).

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