Unterpakete von Spring Autowiring ausschließen?


81

Gibt es eine einfache Möglichkeit, ein Paket / Unterpaket in Spring 3.1 vom Autowiring auszuschließen?

Wenn ich beispielsweise einen Komponentenscan in ein Basispaket von aufnehmen möchte, com.examplegibt es eine einfache Möglichkeit, dies auszuschließen com.example.ignore?

(Warum? Ich möchte einige Komponenten von meinen Integrationstests ausschließen.)

Antworten:


83

Ich bin nicht sicher, ob Sie Pakete explizit mit einem <Ausschluss-Filter> ausschließen können, aber ich wette, die Verwendung eines Regex-Filters würde Sie effektiv dorthin bringen:

 <context:component-scan base-package="com.example">
    <context:exclude-filter type="regex" expression="com\.example\.ignore\..*"/>
 </context:component-scan>

Um es annotationsbasiert zu machen, würden Sie jede Klasse, die Sie für Integrationstests ausgeschlossen haben möchten, mit @ com.example.annotation.ExcludedFromITests kommentieren. Dann würde der Komponentenscan folgendermaßen aussehen:

 <context:component-scan base-package="com.example">
    <context:exclude-filter type="annotation" expression="com.example.annotation.ExcludedFromITests"/>
 </context:component-scan>

Das ist klarer, da Sie jetzt im Quellcode selbst dokumentiert haben, dass die Klasse nicht für Integrationstests in einem Anwendungskontext enthalten sein soll.


Die Verwendung des Ausschlussfilters funktioniert, aber ich musste nicht "."
Amin

1
@Amin Das liegt wahrscheinlich daran, dass "." berücksichtigt jedes Zeichen einschließlich des wörtlichen "."
Aksh1618

54

Ich verwende @ComponentScanFolgendes für denselben Anwendungsfall. Dies entspricht der XML-Antwort von BenSchro10 , verwendet jedoch Anmerkungen. Beide verwenden einen Filter mittype=AspectJ

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration;
import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration;
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ImportResource;

@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan(basePackages = { "com.example" },
    excludeFilters = @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "com.example.ignore.*"))
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Vielleicht ist es reine Nostalgie, aber ich bevorzuge eigentlich immer noch XML
Kirby

10
Ich mag es sein, aber mit Spring 4.2 muss ich FilterType.REGEXfür diesen Ansatz verwenden
ThanksForAllTheFish

Das wollte ich, aber ich musste es auch benutzen FilterType.REGEX. Vielleicht könnte die Antwort aktualisiert werden, um dies widerzuspiegeln?
Adam

1
Fühlen Sie sich frei, eine neue Antwort zu geben
Kirby

36

Für Spring 4 verwende ich Folgendes
(ich poste es, da die Frage 4 Jahre alt ist und mehr Leute Spring 4 als Spring 3.1 verwenden):

@Configuration
@ComponentScan(basePackages = "com.example", 
  excludeFilters = @Filter(type=FilterType.REGEX,pattern="com\\.example\\.ignore\\..*")) 
public class RootConfig {
    // ...
}

13

Es scheint, dass Sie dies über XML getan haben, aber wenn Sie in der neuen Best Practice von Spring arbeiten würden, wäre Ihre Konfiguration in Java, und Sie könnten sie wie folgt ausschließen:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "net.example.tool",
  excludeFilters = {@ComponentScan.Filter(
    type = FilterType.ASSIGNABLE_TYPE,
    value = {JPAConfiguration.class, SecurityConfig.class})
  })

Obwohl Sie feststellen, dass diese Frage älter als 4 Jahre ist und speziell für Spring 3.1 gestellt wurde, oder?
Jonathan W

8
@ JonathanW Aber dennoch eine wirklich nützliche Antwort für Leute, die von einer Google-Suche auf diese Seite kommen
Stewart

12

Dies funktioniert in Spring 3.0.5. Ich würde also denken, dass es in 3.1 funktionieren würde

<context:component-scan base-package="com.example">  
    <context:exclude-filter type="aspectj" expression="com.example.dontscanme.*" />  
</context:component-scan> 

1
Beachten Sie, dass der Ausschluss stillschweigend ignoriert wird, falls Aspektj im Klassenpfad nicht vorhanden ist.
Vadzim

7

Ich denke, Sie sollten Ihre Pakete in einer bequemeren Hierarchie umgestalten, damit sie nicht im Basispaket enthalten sind.

Aber wenn Sie dies nicht können, versuchen Sie:

<context:component-scan base-package="com.example">
    ...
    <context:exclude-filter type="regex" expression="com\.example\.ignore.*"/>
</context:component-scan>

Hier finden Sie weitere Beispiele: Verwenden von Filtern zum Anpassen des Scannens


Vielen Dank, im Prinzip stimme ich der Idee des Refactorings zu - es war mein erster Gedanke. Leider ist es für meine spezielle Situation keine wirklich gute Option.
HolySamosa

Gutes Verpackungsdesign kann diese Situationen vermeiden, aber wenn Sie nicht ... können Sie nicht hahaha, :)
richarbernal

4

Eine Sache, die für mich zu funktionieren scheint, ist folgende:

@ComponentScan(basePackageClasses = {SomeTypeInYourPackage.class}, resourcePattern = "*.class")

Oder in XML:

<context:component-scan base-package="com.example" resource-pattern="*.class"/>

Dies überschreibt den Standard , resourcePatterndas ist "**/*.class".

Dies scheint die typsicherste Möglichkeit zu sein, NUR Ihr Basispaket einzuschließen, da dieses Ressourcenmuster immer dasselbe und relativ zu Ihrem Basispaket ist.


3

Sie können auch @SpringBootApplication verwenden , das laut Spring-Dokumentation dieselbe Funktionalität wie die folgenden drei Anmerkungen bietet : @Configuration , @EnableAutoConfiguration @ComponentScan in einer Anmerkung.

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

1

Sie können auch ein bestimmtes Paket einschließen und ausschließen wie:

Einschließen und Ausschließen (beide)

 @SpringBootApplication
        (
                scanBasePackages = {
                        "com.package1",
                        "com.package2"
                },
                exclude = {org.springframework.boot.sample.class}
        )

NUR ausschließen

@SpringBootApplication(exclude= {com.package1.class})
public class MySpringConfiguration {}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.