Scanning af fjederkomponenter

1. Oversigt

I denne vejledning vil vi dække komponentscanning i foråret. Når vi arbejder med Spring, kan vi kommentere vores klasser for at gøre dem til Spring beans. Men udover det vi kan fortælle Spring, hvor vi skal søge efter disse kommenterede klasser da ikke alle af dem skal blive bønner i denne særlige kørsel.

Selvfølgelig er der nogle standarder for komponentscanning, men vi kan også tilpasse pakkerne til søgning.

Lad os først se på standardindstillingerne.

2. @ComponentScan Uden argumenter

2.1. Ved brug af @ComponentScan i en Spring Application

Med foråret, vi bruger @ComponentScan kommentar sammen med @Konfiguration kommentar for at specificere de pakker, som vi vil scanne. @ComponentScan uden argumenter beder Spring om at scanne den aktuelle pakke og alle dens underpakker.

Lad os sige, at vi har følgende @Konfiguration i com.baeldung.componentscan.springapp pakke:

@Configuration @ComponentScan offentlig klasse SpringComponentScanApp {privat statisk ApplicationContext applicationContext; @Bean public ExampleBean exampleBean () {returner nyt ExampleBean (); } public static void main (String [] args) {applicationContext = new AnnotationConfigApplicationContext (SpringComponentScanApp.class); for (String beanName: applicationContext.getBeanDefinitionNames ()) {System.out.println (beanName); }}}

Lad os også sige, at vi har Kat og Hund komponenter i com.baeldung.componentscan.springapp.dyr pakke:

pakke com.baeldung.componentscan.springapp.animals; // ... @Komponent offentlig klasse Cat {}
pakke com.baeldung.componentscan.springapp.animals; // ... @Komponent offentlig klasse hund {}

Og endelig har vi Rose komponent i com.baeldung.componentscan.springapp.blomster pakke:

pakke com.baeldung.componentscan.springapp.flowers; // ... @Komponent offentlig klasse Rose {}

Resultatet af hoved () metoden indeholder alle bønner af com.baeldung.componentscan.springapp pakke og dens underpakker:

springComponentScanApp kattehund rose eksempelBønne

Bemærk, at hovedapplikationsklassen også er en bønne, da den er kommenteret @Konfiguration, hvilket er en @Komponent.

Bemærk også, at hovedapplikationsklassen og konfigurationsklassen ikke nødvendigvis er den samme. Hvis de er forskellige, betyder det ikke noget, hvor hovedapplikationsklassen skal placeres. Kun placeringen af ​​konfigurationsklassen betyder noget, da komponentscanning starter fra sin pakke som standard.

Endelig bemærk det i vores eksempel @ComponentScan svarer til:

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

hvor basePackages argument er en pakke eller en række pakker til scanning.

2.2. Ved brug af @ComponentScan i en Spring Boot-applikation

Tricket med Spring Boot er, at mange ting sker implicit. Vi bruger @SpringBootApplication kommentar, men det er bare en kombination af tre kommentarer:

@Configuration @EnableAutoConfiguration @ComponentScan

Lad os oprette en lignende struktur i com.baeldung.componentscan.springbootapp pakke. Denne gang vil hovedapplikationen være:

pakke com.baeldung.componentscan.springbootapp; // ... @ SpringBootApplication offentlig klasse SpringBootComponentScanApp {privat statisk ApplicationContext applicationContext; @Bean public ExampleBean exampleBean () {returner nyt ExampleBean (); } offentlig statisk ugyldig hoved (String [] args) {applicationContext = SpringApplication.run (SpringBootComponentScanApp.class, args); checkBeansPresence ("cat", "dog", "rose", "exampleBean", "springBootComponentScanApp"); } privat statisk ugyldig checkBeansPresence (String ... beans) {for (String beanName: beans) {System.out.println ("Er" + beanName + "i ApplicationContext:" + applicationContext.containsBean (beanName)); }}}

Alle andre pakker og klasser forbliver de samme, vi kopierer dem bare til det nærliggende com.baeldung.componentscan.springbootapp pakke.

Spring Boot scanner pakker på samme måde som vores tidligere eksempel. Lad os kontrollere output:

Er kat i ApplicationContext: sand Er hund i ApplicationContext: sand Er steg i ApplicationContext: true Er eksempelBean i ApplicationContext: true Er springBootComponentScanApp i ApplicationContext: true

Årsagen til, at vi bare kontrollerer bønnerne for eksistens i vores andet eksempel (i modsætning til at udskrive alle bønner) er, at output ville være for stort.

Dette er på grund af det implicitte @EnableAutoConfiguration kommentar, der får Spring Boot til at oprette mange bønner automatisk, afhængigt af afhængighederne i pom.xml fil.

3. @ComponentScan Med argumenter

Lad os nu tilpasse stierne til scanning. Lad os for eksempel sige, at vi vil ekskludere Rose bønne.

3.1. @ComponentScan til specifikke pakker

Vi kan gøre det på et par måder. For det første kan vi ændre basispakken:

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

Nu vil output være:

springComponentScanApp kattehund eksempelBønne

Lad os se, hvad der ligger bag dette:

  • springComponentScanApp oprettes, da det er en konfiguration, der sendes som et argument til AnnotationConfigApplicationContext
  • eksempelBønne er en bønne konfigureret inde i konfigurationen
  • kat og hund er i det angivne com.baeldung.componentscan.springapp.animaler pakke

Alle ovennævnte tilpasninger gælder også i Spring Boot. Vi kan bruge @ComponentScan sammen med @SpringBootApplication og resultatet bliver det samme:

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

3.2. @ComponentScan med undtagelser

En anden måde er at bruge et filter, der angiver mønsteret for de klasser, der skal udelukkes:

@ComponentScan (excludeFilters = @ ComponentScan.Filter (type = FilterType.REGEX, mønster = "com \. Baeldung \. Komponenter kan \. Springapp \. Blomster \ .. *"))

Vi kan også vælge en anden filtertype, som kommentaren understøtter flere fleksible muligheder for filtrering af de scannede klasser:

@ComponentScan (excludeFilters = @ ComponentScan.Filter (type = FilterType.ASSIGNABLE_TYPE, værdi = Rose.class))

4. Standardpakken

Vi bør undgå at sætte @Konfiguration klasse i standardpakken (dvs. ved slet ikke at specificere pakken). I dette tilfælde scanner Spring alle klasserne i alle krukker i en klassesti. Det forårsager fejl, og applikationen starter sandsynligvis ikke.

5. Konklusion

I denne artikel har vi lært, hvilke pakker Spring scanner som standard, og hvordan man tilpasser disse stier.

Som sædvanlig er den komplette kode tilgængelig på GitHub.