Spring BeanCreationException

1. Oversigt

I denne artikel diskuterer vi Forår org.springframework.beans.factory.BeanCreationException - dette er en meget almindelig undtagelse, der kastes, når BeanFactory opretter bønner med bønnedefinitionerne og støder på et problem. Artiklen diskuterer de mest almindelige årsager til denne undtagelse sammen med løsningen.

2. Årsag: org.springframework.beans.factory.NoSuchBeanDefinitionException

Langt den mest almindelige årsag til BeanCreationException prøver foråret at indsprøjt en bønne, der ikke findes i sammenhængen.

For eksempel, BeanA prøver at injicere BeanB:

@Komponent offentlig klasse BeanA {@Autowired privat BeanB-afhængighed; ...}

Hvis en BeanB findes ikke i sammenhængen, kastes følgende undtagelse (Fejl ved oprettelse af bønne):

Fejl ved oprettelse af bønne med navnet 'beanA': Injektion af autowired-afhængigheder mislykkedes; indlejret undtagelse er org.springframework.beans.factory.BeanCreationException: Kunne ikke autowire felt: privat com.baeldung.web.BeanB cpm.baeldung.web.BeanA.dependency; indlejret undtagelse er org.springframework.beans.factory.NoSuchBeanDefinitionException: Ingen kvalificerende bønne af typen [com.baeldung.web.BeanB] fundet for afhængighed: forventes mindst 1 bønne, der kvalificerer som autowire-kandidat for denne afhængighed. Afhængighedsannotationer: {@ org.springframework.beans.factory.annotation.Autowired (krævet = true)}

For at diagnosticere denne type problem - sørg først for, at bønnen er erklæret:

  • enten i en XML-konfigurationsfil ved hjælp af element
  • eller i en Java @Konfiguration klasse via @Bønne kommentar
  • eller er kommenteret med: @Komponent, @Repository, @Service, @Kontrol og classpath scanning er aktiv for den pakke

Kontroller også, at konfigurationsfilerne eller klasserne faktisk er hentet af Spring og indlæst i hovedkonteksten.

3. Årsag: org.springframework.beans.factory.NoUniqueBeanDefinitionException

En anden lignende årsag til undtagelsen for oprettelse af bønner er Spring, der prøver at injicere en bønne efter type - nemlig ved dens grænseflade - og finde to eller flere bønner, der implementerer denne grænseflade i sammenhængen.

For eksempel, BønneB1 og BeanB2 begge implementerer den samme grænseflade:

@Komponent offentlig klasse BeanB1 implementerer IBeanB {...} @Komponent offentlig klasse BeanB2 implementerer IBeanB {...} @Komponent offentlig klasse BeanA {@Autowired privat IBeanB-afhængighed; ...}

Dette vil føre til at følgende undtagelse kastes af Spring Bean Factory:

Fejl ved oprettelse af bønne med navnet 'beanA': Injektion af autowired-afhængigheder mislykkedes; nestet undtagelse er org.springframework.beans.factory.BeanCreationException: Kunne ikke autowire felt: privat com.baeldung.web.IBeanB com.baeldung.web.BeanA.b; nestet undtagelse er org.springframework.beans.factory.NoUniqueBeanDefinitionException: Ingen kvalificerende bønne af typen [com.baeldung.web.IBeanB] er defineret: forventet enkelt matchende bønne men fundet 2: beanB1, beanB2

4. Årsag: org.springframework.beans.BeanInstantiationException

4.1. Brugerdefineret undtagelse

Næste i køen er en bønne, der kaster en undtagelse under oprettelsesprocessen; en forenklet prøve for let at eksemplificere og forstå problemet kaster en undtagelse i bønnens konstruktør:

@Komponent offentlig klasse BeanA {offentlig BeanA () {super (); smid nyt NullPointerException (); } ...}

Som forventet vil dette føre til, at foråret fejler hurtigt med følgende undtagelse:

Fejl ved oprettelse af bønne med navnet 'beanA' defineret i fil [... BeanA.class]: Instantiering af bønne mislykkedes; nestet undtagelse er org.springframework.beans.BeanInstantiationException: Kunne ikke instantere bønne klasse [com.baeldung.web.BeanA]: Konstruktør kastede undtagelse; nestet undtagelse er java.lang.NullPointerException

4.2. java.lang.InstantiationException

En anden mulig forekomst af BeanInstantiationException definerer en abstrakt klasse som en bønne i XML; dette skal være i XML, fordi der ikke er nogen måde at gøre dette i en Java @Configuration-fil, og klassesti-scanning ignorerer den abstrakte klasse:

@Komponent offentlig abstrakt klasse BeanA implementerer IBeanA {...}

Og XML-definitionen af ​​bønnen:

Denne opsætning vil resultere i en lignende undtagelse:

org.springframework.beans.factory.BeanCreationException: Fejl ved oprettelse af bønne med navnet 'beanA' defineret i klasse stieressource [beansInXml.xml]: Instantiering af bønne mislykkedes; nestet undtagelse er org.springframework.beans.BeanInstantiationException: Kunne ikke instantere bønneklassen [com.baeldung.web.BeanA]: Er det en abstrakt klasse ?; nestet undtagelse er java.lang.InstantiationException

4.3. java.lang.NoSuchMethodException

Hvis en bønne ikke har nogen standardkonstruktør, og Spring forsøger at instantiere den ved at lede efter den konstruktør, vil dette resultere i en runtime-undtagelse for eksempel:

@Komponent offentlig klasse BeanA implementerer IBeanA {public BeanA (endelig strengnavn) {super (); System.out.println (navn); }}

Når denne bønne samles op af klassesti-scanningsmekanismen, vil fejlen være:

Fejl ved oprettelse af bønne med navnet 'beanA' defineret i fil [... BeanA.class]: Instantiering af bønne mislykkedes; nestet undtagelse er org.springframework.beans.BeanInstantiationException: Kunne ikke instantere bønneklassen [com.baeldung.web.BeanA]: Ingen standardkonstruktør fundet; indlejret undtagelse er java.lang.NoSuchMethodException: com.baeldung.web.BeanA. ()

En lignende undtagelse, men sværere at diagnosticere, kan forekomme, når forårets afhængighed på klassestien ikke har samme version; denne form for version inkompatibilitet kan resultere i en NoSuchMethodException på grund af API-ændringer. Løsningen på et sådant problem er at sikre, at alle Spring-biblioteker har nøjagtig den samme version i projektet.

5. Årsag: org.springframework.beans.NotWritablePropertyException

Endnu en mulighed er at definere en bønne - BeanA - med en henvisning til en anden bønne - BeanB - uden at have den tilsvarende settermetode i BeanA:

@Komponent offentlig klasse BeanA {privat IBeanB-afhængighed; ...} @Komponent offentlig klasse BeanB implementerer IBeanB {...}

Og forårets XML-konfiguration:

Igen, dette kan kun forekomme i XML-konfiguration, fordi når du bruger Java @Konfiguration, vil compileren gøre dette emne umuligt at reproducere.

Selvfølgelig skal sætteren tilføjes for at løse dette problem IBeanB:

@Komponent offentlig klasse BeanA {privat IBeanB-afhængighed; public void setDependency (final IBeanB dependency) {this.dependency = dependency; }}

6. Årsag: org.springframework.beans.factory.CannotLoadBeanClassException

Denne undtagelse kastes når Foråret kan ikke indlæse klassen for den definerede bønne - dette kan ske, hvis Spring XML-konfigurationen indeholder en bønne, der simpelthen ikke har en tilsvarende klasse. For eksempel hvis klasse BeanZ findes ikke, vil følgende definition resultere i en undtagelse:

Grundårsagen, hvis ClassNotFoundException og den fulde undtagelse i dette tilfælde er:

indlejret undtagelse er org.springframework.beans.factory.BeanCreationException: ... indlejret undtagelse er org.springframework.beans.factory.CannotLoadBeanClassException: Kan ikke finde klasse [com.baeldung.web.BeanZ] for bønne med navnet 'beanZ' defineret i klasse sti ressource [beansInXml.xml]; indlejret undtagelse er java.lang.ClassNotFoundException: com.baeldung.web.BeanZ

7. Børn af BeanCreationException

7.1. Det org.springframework.beans.factory.BeanCurrentlyInCreationException

En af underklasserne til BeanCreationException er BeanCurrentlyInCreationException; dette sker normalt, når man bruger konstruktionsinjektion - for eksempel i tilfælde af cirkulære afhængigheder:

@Komponent offentlig klasse BeanA implementerer IBeanA {privat IBeanB beanB; @Autowired public BeanA (final IBeanB beanB) {super (); this.beanB = beanB; }} @Komponent offentlig klasse BeanB implementerer IBeanB {final IBeanA beanA; @Autowired public BeanB (final IBeanA beanA) {super (); this.beanA = beanA; }}

Foråret vil ikke være i stand til at løse denne form for ledningsføring, og slutresultatet bliver:

org.springframework.beans.factory.BeanCurrentlyInCreationException: Fejl ved oprettelse af bønne med navnet 'beanA': Den anmodede bønne er i øjeblikket under oprettelse: Er der en uopløselig cirkulær reference?

Den fulde undtagelse er meget detaljeret:

org.springframework.beans.factory.UnsatisfiedDependencyException: Fejl ved oprettelse af bønne med navnet 'beanA' defineret i fil [... BeanA.class]: Utilfreds afhængighed udtrykt gennem konstruktørargument med indeks 0 af typen [com.baeldung.web.IBeanB] :: Fejl ved oprettelse af bønne med navnet 'beanB' defineret i fil [... BeanB.class]: Utilfreds afhængighed udtrykt gennem konstruktørargument med indeks 0 af typen [com.baeldung.web.IBeanA]:: Fejl ved oprettelse af bønne med navn ' beanA ': Den anmodede bønne er i øjeblikket under oprettelse: Er der en uløselig cirkulær reference ?; nestet undtagelse er org.springframework.beans.factory.BeanCurrentlyInCreationException: Fejl ved oprettelse af bønne med navnet 'beanA': Den anmodede bønne er i øjeblikket under oprettelse: Er der en uopløselig cirkulær reference ?; nestet undtagelse er org.springframework.beans.factory.UnsatisfiedDependencyException: Fejl ved oprettelse af bønne med navnet 'beanB' defineret i fil [... BeanB.class]: Utilfreds afhængighed udtrykt gennem konstruktørargument med indeks 0 af typen [com.baeldung.web .IBeanA]:: Fejl ved oprettelse af bønne med navnet 'beanA': Den anmodede bønne er i øjeblikket under oprettelse: Er der en uopløselig cirkulær reference ?; nestet undtagelse er org.springframework.beans.factory.BeanCurrentlyInCreationException: Fejl ved oprettelse af bønne med navnet 'beanA': Den anmodede bønne er i øjeblikket ved oprettelse: Er der en uopløselig cirkulær reference?

7.2. Det org.springframework.beans.factory.BeanIsAbstractException

Denne undtagelse til instantiering kan forekomme, når Bean Factory prøver at hente og instantiere en bønne, der blev erklæret som abstrakt; for eksempel:

offentlig abstrakt klasse BeanA implementerer IBeanA {...}

Erklæret i XML-konfigurationen som:

Nu, hvis vi prøver at hente BeanA fra Spring Context ved navn - for eksempel når man instantierer en anden bønne:

@Configuration public class Config {@Autowired BeanFactory beanFactory; @Bean offentlig BeanB beanB () {beanFactory.getBean ("beanA"); returner ny BeanB (); }}

Dette vil resultere i følgende undtagelse:

org.springframework.beans.factory.BeanIsAbstractException: Fejl ved oprettelse af bønne med navnet 'beanA': Bønnedefinition er abstrakt

Og den fulde undtagelse stacktrace:

org.springframework.beans.factory.BeanCreationException: Fejl ved oprettelse af bønne med navnet 'beanB' defineret i klasse stieressource [org / baeldung / spring / config / WebConfig.class]: Instantiering af bønne mislykkedes; indlejret undtagelse er org.springframework.beans.factory.BeanDefinitionStoreException: Fabriksmetode [public com.baeldung.web.BeanB com.baeldung.spring.config.WebConfig.beanB ()] kastede undtagelse; nestet undtagelse er org.springframework.beans.factory.BeanIsAbstractException: Fejl ved oprettelse af bønne med navnet 'beanA': Bønnedefinition er abstrakt

8. Konklusion

I slutningen af ​​denne artikel skal vi have et klart kort til at navigere i forskellige årsager og problemer, der kan føre til en BeanCreationException om foråret samt en god forståelse af, hvordan man løser alle disse problemer.

Implementeringen af ​​alle eksempler på undtagelser findes i github-projektet - dette er et Eclipse-baseret projekt, så det skal være let at importere og køre som det er.