Scannen van veercomponenten

1. Overzicht

In deze zelfstudie behandelen we het scannen van componenten in het voorjaar. Als we met Spring werken, kunnen we onze lessen annoteren om er Springbonen van te maken. Maar daarnaast, we kunnen Spring vertellen waar ze naar deze geannoteerde klassen moet zoeken omdat ze niet allemaal bonen moeten worden in deze specifieke run.

Natuurlijk zijn er enkele standaardinstellingen voor het scannen van componenten, maar we kunnen de pakketten ook aanpassen voor zoeken.

Laten we eerst eens kijken naar de standaardinstellingen.

2. @BuienRadarNL Zonder argumenten

2.1. Gebruik makend van @BuienRadarNL in een voorjaarstoepassing

Met de lente, wij gebruiken de @BuienRadarNL annotatie samen met @Configuratie annotatie om de pakketten te specificeren die we willen scannen. @BuienRadarNL zonder argumenten vertelt Spring om het huidige pakket en al zijn subpakketten te scannen.

Laten we zeggen dat we het volgende hebben @Configuratie in com.baeldung.componentscan.springapp pakket:

@Configuration @ComponentScan openbare klasse SpringComponentScanApp {privé statische ApplicationContext applicationContext; @Bean openbaar ExampleBean exampleBean () {return new ExampleBean (); } public static void main (String [] args) {applicationContext = new AnnotationConfigApplicationContext (SpringComponentScanApp.class); voor (String beanName: applicationContext.getBeanDefinitionNames ()) {System.out.println (beanName); }}}

Laten we ook zeggen dat we de Kat en Hond componenten in com.baeldung.componentscan.springapp.dieren pakket:

pakket com.baeldung.componentscan.springapp.animals; // ... @Component openbare klasse Cat {}
pakket com.baeldung.componentscan.springapp.animals; // ... @Component openbare klasse Hond {}

En tot slot hebben we de Roos component in com.baeldung.componentscan.springapp.flowers pakket:

pakket com.baeldung.componentscan.springapp.flowers; // ... @Component openbare klasse Rose {}

De output van de hoofd() methode bevat alle bonen van com.baeldung.componentscan.springapp pakket en van zijn subpakketten:

springComponentScanApp kat hond roos voorbeeldBean

Merk op dat de hoofdtoepassingsklasse ook een boon is zoals deze is geannoteerd @Configuratie, wat een is @Component.

Merk ook op dat de hoofdtoepassingsklasse en de configuratieklasse niet noodzakelijk hetzelfde zijn. Als ze verschillend zijn, maakt het niet uit waar de hoofdtoepassingsklasse moet worden geplaatst. Alleen de locatie van de configuratieklasse is van belang, aangezien het scannen van componenten standaard vanuit het pakket begint.

Merk ten slotte op dat in ons voorbeeld @BuienRadarNL is gelijk aan:

@ComponentScan (basePackages = "com.baeldung.componentscan.springapp")

waar basePackages argument is een pakket of een reeks pakketten om te scannen.

2.2. Gebruik makend van @BuienRadarNL in een Spring Boot-applicatie

De truc met Spring Boot is dat veel dingen impliciet gebeuren. Wij gebruiken de @SpringBootApplication annotatie, maar het is slechts een combinatie van drie annotaties:

@Configuratie @EnableAutoConfiguration @ComponentScan

Laten we een vergelijkbare structuur maken in com.baeldung.componentscan.springbootapp pakket. Deze keer is de belangrijkste toepassing:

pakket com.baeldung.componentscan.springbootapp; // ... @SpringBootApplication openbare klasse SpringBootComponentScanApp {privé statische ApplicationContext applicationContext; @Bean openbaar ExampleBean exampleBean () {return new ExampleBean (); } openbare statische leegte hoofd (String [] args) {applicationContext = SpringApplication.run (SpringBootComponentScanApp.class, args); checkBeansPresence ("kat", "hond", "rose", "exampleBean", "springBootComponentScanApp"); } private static void checkBeansPresence (String ... beans) {for (String beanName: beans) {System.out.println ("Is" + beanName + "in ApplicationContext:" + applicationContext.containsBean (beanName)); }}}

Alle andere pakketten en klassen blijven hetzelfde, we kopiëren ze gewoon naar het nabijgelegen com.baeldung.componentscan.springbootapp pakket.

Spring Boot scant pakketten op dezelfde manier als in ons vorige voorbeeld. Laten we de uitvoer bekijken:

Is kat in ApplicationContext: true Is hond in ApplicationContext: true Is roos in ApplicationContext: true Is exampleBean in ApplicationContext: true Is springBootComponentScanApp in ApplicationContext: true

De reden dat we de bonen in ons tweede voorbeeld controleren op bestaan ​​(in plaats van alle bonen af ​​te drukken), is dat de uitvoer te groot zou zijn.

Dit komt door het impliciete @EnableAutoConfiguration annotatie waardoor Spring Boot automatisch veel bonen maakt, afhankelijk van de afhankelijkheden in pom.xml het dossier.

3. @BuienRadarNL Met argumenten

Laten we nu de paden voor scannen aanpassen. Laten we bijvoorbeeld zeggen dat we de Roos Boon.

3.1. @BuienRadarNL voor specifieke pakketten

We kunnen het op een paar manieren doen. Ten eerste kunnen we het basispakket wijzigen:

@ComponentScan (basePackages = "com.baeldung.componentscan.springapp.animals") @ Configuratie openbare klasse SpringComponentScanApp {// ...}

Nu zal de output zijn:

springComponentScanApp kat hond voorbeeldBean

Laten we eens kijken wat hierachter zit:

  • springComponentScanApp wordt gemaakt omdat het een configuratie is die als argument is doorgegeven aan de AnnotationConfigApplicationContext
  • voorbeeldBean is een boon geconfigureerd in de configuratie
  • kat en hond zijn in de opgegeven com.baeldung.componentscan.springapp.dieren pakket

Alle hierboven genoemde aanpassingen zijn ook van toepassing in Spring Boot. We kunnen gebruiken @BuienRadarNL samen met @SpringBootApplication en het resultaat zal hetzelfde zijn:

@SpringBootApplication @ComponentScan (basePackages = "com.baeldung.componentscan.springbootapp.animals")

3.2. @BuienRadarNL met uitsluitingen

Een andere manier is om een ​​filter te gebruiken, waarbij u het patroon specificeert voor de klassen die moeten worden uitgesloten:

@ComponentScan (excludeFilters = @ ComponentScan.Filter (type = FilterType.REGEX, patroon = "com \. Baeldung \. Componentscan \. Springapp \. Bloemen \ .. *"))

We kunnen ook een ander filtertype kiezen, zoals de annotatie ondersteunt verschillende flexibele opties voor het filteren van de gescande klassen:

@ComponentScan (excludeFilters = @ ComponentScan.Filter (type = FilterType.ASSIGNABLE_TYPE, waarde = Rose.class))

4. Het standaardpakket

We moeten voorkomen dat de @Configuratie class in het standaardpakket (d.w.z. door het pakket helemaal niet op te geven). In dit geval scant Spring alle klassen in alle potten in een klassenpad. Dat veroorzaakt fouten en de applicatie start waarschijnlijk niet.

5. Conclusie

In dit artikel hebben we geleerd welke pakketten Spring standaard scant en hoe deze paden kunnen worden aangepast.

Zoals gewoonlijk is de volledige code beschikbaar op GitHub.