Spring BeanCreationException

1. Overzicht

In dit artikel bespreken we de Voorjaar org.springframework.beans.factory.BeanCreationException - dit is een veel voorkomende uitzondering die wordt gegenereerd wanneer de BeanFactory maakt bonen van de bean-definities en komt een probleem tegen. In het artikel worden de meest voorkomende oorzaken van deze uitzondering samen met de oplossing besproken.

2. Oorzaak: org.springframework.beans.factory.NoSuchBeanDefinitionException

Veruit de meest voorkomende oorzaak van de BeanCreationException probeert de lente injecteer een boon die niet bestaat in de context.

Bijvoorbeeld, BeanA probeert te injecteren BeanB:

@Component openbare klasse BeanA {@Autowired privé BeanB-afhankelijkheid; ...}

Als een BeanB wordt niet gevonden in de context, dan wordt de volgende uitzondering gegenereerd (Fout bij het maken van Bean):

Fout bij het maken van bean met de naam 'beanA': injectie van automatisch bedrade afhankelijkheden is mislukt; geneste uitzondering is org.springframework.beans.factory.BeanCreationException: Kan veld niet automatisch bedraden: privé com.baeldung.web.BeanB cpm.baeldung.web.BeanA.dependency; geneste uitzondering is org.springframework.beans.factory.NoSuchBeanDefinitionException: Geen kwalificerende bean van het type [com.baeldung.web.BeanB] gevonden voor afhankelijkheid: verwacht ten minste 1 bean die kwalificeert als autowire-kandidaat voor deze afhankelijkheid. Afhankelijkheidsaantekeningen: {@ org.springframework.beans.factory.annotation.Autowired (vereist = waar)}

Om dit type probleem te diagnosticeren - zorg er eerst voor dat de boon wordt gedeclareerd:

  • ofwel in een XML-configuratiebestand met behulp van de element
  • of in een Java @Configuratie klasse via de @Boon annotatie
  • of is geannoteerd met: @Component, @Repository, @Onderhoud, @Controller en classpath scanning is actief voor dat pakket

Controleer ook of de configuratiebestanden of klassen daadwerkelijk door Spring worden opgepikt en in de hoofdcontext worden geladen.

3. Oorzaak: org.springframework.beans.factory.NoUniqueBeanDefinitionException

Een andere soortgelijke oorzaak voor de uitzondering voor het maken van bonen is dat Spring probeert een boon te injecteren op type - namelijk via de interface - en het vinden twee of meer bean die die interface implementeren in de context.

Bijvoorbeeld, Boon B1 en BeanB2 beide implementeren dezelfde interface:

@Component openbare klasse BeanB1 implementeert IBeanB {...} @Component openbare klasse BeanB2 implementeert IBeanB {...} @Component openbare klasse BeanA {@Autowired privé IBeanB-afhankelijkheid; ...}

Dit zal ertoe leiden dat de volgende uitzondering wordt gegenereerd door de Spring Bean-fabriek:

Fout bij het maken van bean met de naam 'beanA': injectie van automatisch bedrade afhankelijkheden is mislukt; geneste uitzondering is org.springframework.beans.factory.BeanCreationException: Kan veld niet automatisch bedraden: privé com.baeldung.web.IBeanB com.baeldung.web.BeanA.b; geneste uitzondering is org.springframework.beans.factory.NoUniqueBeanDefinitionException: er is geen kwalificerende bean van het type [com.baeldung.web.IBeanB] gedefinieerd: verwachte enkele overeenkomende bean maar gevonden 2: beanB1, beanB2

4. Oorzaak: org.springframework.beans.BeanInstantiationException

4.1. Aangepaste uitzondering

De volgende in de rij is een bean die een uitzondering genereert tijdens het aanmaakproces; een vereenvoudigd voorbeeld om het probleem gemakkelijk te illustreren en te begrijpen, is het gooien van een uitzondering in de constructor van de bean:

@Component openbare klasse BeanA {openbare BeanA () {super (); gooi nieuwe NullPointerException (); } ...}

Zoals verwacht zal dit ertoe leiden dat Spring snel faalt, met de volgende uitzondering:

Fout bij maken van bean met naam 'beanA' gedefinieerd in bestand [... BeanA.class]: Instantiatie van bean is mislukt; geneste uitzondering is org.springframework.beans.BeanInstantiationException: kon bean class [com.baeldung.web.BeanA] niet instantiëren: constructor gooide een uitzondering; geneste uitzondering is java.lang.NullPointerException

4.2. java.lang.InstantiationException

Een ander mogelijk voorkomen van de BeanInstantiationException definieert een abstracte klasse als een bean in XML; dit moet in XML zijn, omdat er geen manier is om dit te doen in een Java @ Configuratie-bestand en het scannen van klassenpaden negeert de abstracte klasse:

@Component openbare abstracte klasse BeanA implementeert IBeanA {...}

En de XML-definitie van de boon:

Deze opstelling resulteert in een vergelijkbare uitzondering:

org.springframework.beans.factory.BeanCreationException: Fout bij het maken van bean met de naam 'beanA' gedefinieerd in klassenpadresource [beansInXml.xml]: instantiëren van bean is mislukt; geneste uitzondering is org.springframework.beans.BeanInstantiationException: Kon de bean-klasse niet instantiëren [com.baeldung.web.BeanA]: is het een abstracte klasse ?; geneste uitzondering is java.lang.InstantiationException

4.3. java.lang.NoSuchMethodException

Als een bean geen standaardconstructor heeft en Spring probeert deze te instantiëren door naar die constructor te zoeken, zal dit resulteren in een runtime-uitzondering; bijvoorbeeld:

@Component openbare klasse BeanA implementeert IBeanA {openbare BeanA (laatste String-naam) {super (); System.out.println (naam); }}

Wanneer deze bean wordt opgepikt door het classpath-scanmechanisme, is de fout:

Fout bij het maken van bean met de naam 'beanA' gedefinieerd in bestand [... BeanA.class]: Instantiatie van bean is mislukt; geneste uitzondering is org.springframework.beans.BeanInstantiationException: Kan bean-klasse [com.baeldung.web.BeanA] niet starten: geen standaardconstructor gevonden; geneste uitzondering is java.lang.NoSuchMethodException: com.baeldung.web.BeanA. ()

Een soortgelijke uitzondering, maar moeilijker te diagnosticeren, kan optreden wanneer de Spring-afhankelijkheden op het klassenpad niet de dezelfde versie; dit soort versie-incompatibiliteit kan resulteren in een NoSuchMethodException vanwege API-wijzigingen. De oplossing voor een dergelijk probleem is ervoor te zorgen dat alle Spring-bibliotheken exact dezelfde versie in het project hebben.

5. Oorzaak: org.springframework.beans.NotWritablePropertyException

Nog een andere mogelijkheid is het definiëren van een boon - BeanA - met een verwijzing naar een andere boon - BeanB - zonder de bijbehorende setter-methode in BeanA:

@Component openbare klasse BeanA {privé IBeanB-afhankelijkheid; ...} @Component openbare klasse BeanB implementeert IBeanB {...}

En de Spring XML-configuratie:

Nogmaals, dit kan alleen voorkomen in XML-configuratie, omdat bij het gebruik van Java @Configuratie, maakt de compiler het onmogelijk om dit probleem te reproduceren.

Om dit probleem op te lossen, moet natuurlijk de setter worden toegevoegd IBeanB:

@Component openbare klasse BeanA {privé IBeanB-afhankelijkheid; public void setDependency (laatste IBeanB-afhankelijkheid) {this.dependency = afhankelijkheid; }}

6. Oorzaak: org.springframework.beans.factory.CannotLoadBeanClassException

Deze uitzondering wordt gegenereerd wanneer De lente kan de klasse van de gedefinieerde boon niet laden - dit kan gebeuren als de Spring XML-configuratie een bean bevat die simpelweg geen overeenkomstige klasse heeft. Als class BeanZ bestaat niet, zal de volgende definitie resulteren in een uitzondering:

De hoofdoorzaak als het ClassNotFoundException en de volledige uitzondering in dit geval is:

geneste uitzondering is org.springframework.beans.factory.BeanCreationException: ... geneste uitzondering is org.springframework.beans.factory.CannotLoadBeanClassException: Kan klasse [com.baeldung.web.BeanZ] niet vinden voor bean met de naam 'beanZ' gedefinieerd in klassenpadbron [beansInXml.xml]; geneste uitzondering is java.lang.ClassNotFoundException: com.baeldung.web.BeanZ

7. Kinderen van BeanCreationException

7.1. De org.springframework.beans.factory.BeanCurrentlyInCreationException

Een van de subklassen van BeanCreationException is de BeanCurrentlyInCreationException; dit gebeurt meestal bij het gebruik van constructor-injectie - bijvoorbeeld in het geval van circulaire afhankelijkheden:

@Component openbare klasse BeanA implementeert IBeanA {privé IBeanB beanB; @Autowired openbare BeanA (laatste IBeanB beanB) {super (); this.beanB = beanB; }} @Component openbare klasse BeanB implementeert IBeanB {final IBeanA beanA; @Autowired openbare BeanB (laatste IBeanA beanA) {super (); this.beanA = beanA; }}

Spring kan dit soort bedradingsscenario niet oplossen en het eindresultaat is:

org.springframework.beans.factory.BeanCurrentlyInCreationException: Fout bij het maken van bean met de naam 'beanA': de aangevraagde bean wordt momenteel gemaakt: is er een onoplosbare kringverwijzing?

De volledige uitzondering is erg uitgebreid:

org.springframework.beans.factory.UnsatisfiedDependencyException: fout bij het maken van bean met de naam 'beanA' gedefinieerd in bestand [... BeanA.class]: ontevredenheid uitgedrukt door constructorargument met index 0 van het type [com.baeldung.web.IBeanB] :: Fout bij maken van bean met naam 'beanB' gedefinieerd in bestand [... BeanB.class]: Onvoldane afhankelijkheid uitgedrukt door constructorargument met index 0 van het type [com.baeldung.web.IBeanA]:: Fout bij maken van bean met naam ' beanA ': de aangevraagde boon wordt momenteel gemaakt: is er een onoplosbare kringverwijzing ?; geneste uitzondering is org.springframework.beans.factory.BeanCurrentlyInCreationException: Fout bij het maken van bean met de naam 'beanA': de aangevraagde bean wordt momenteel gemaakt: is er een onoplosbare kringverwijzing ?; geneste uitzondering is org.springframework.beans.factory.UnsatisfiedDependencyException: fout bij het maken van bean met de naam 'beanB' gedefinieerd in bestand [... BeanB.class]: ontevredenheid uitgedrukt door constructorargument met index 0 van het type [com.baeldung.web .IBeanA]:: Fout bij het maken van een bean met de naam 'beanA': de aangevraagde bean wordt momenteel gemaakt: is er een onoplosbare kringverwijzing ?; geneste uitzondering is org.springframework.beans.factory.BeanCurrentlyInCreationException: Fout bij het maken van bean met de naam 'beanA': de aangevraagde bean wordt momenteel gemaakt: is er een onoplosbare kringverwijzing?

7.2. De org.springframework.beans.factory.BeanIsAbstractException

Deze instantiatie-uitzondering kan optreden wanneer de Bean Factory een bean probeert op te halen en te instantiëren die als abstract is gedeclareerd; bijvoorbeeld:

openbare abstracte klasse BeanA implementeert IBeanA {...}

Aangegeven in de XML-configuratie als:

Nu, als we het proberen ophalen BeanA uit de Spring Context op naam - bijvoorbeeld bij het instantiëren van een andere boon:

@ Configuratie openbare klasse Config {@Autowired BeanFactory beanFactory; @Bean openbare BeanB beanB () {beanFactory.getBean ("beanA"); retourneer nieuwe BeanB (); }}

Dit resulteert in de volgende uitzondering:

org.springframework.beans.factory.BeanIsAbstractException: fout bij het maken van boon met naam 'beanA': boondefinitie is abstract

En de volledige uitzondering stacktrace:

org.springframework.beans.factory.BeanCreationException: Fout bij maken van bean met naam 'beanB' gedefinieerd in klassenpadresource [org / baeldung / spring / config / WebConfig.class]: instantiëren van bean is mislukt; geneste uitzondering is org.springframework.beans.factory.BeanDefinitionStoreException: Fabrieksmethode [openbare com.baeldung.web.BeanB com.baeldung.spring.config.WebConfig.beanB ()] heeft een uitzondering veroorzaakt; geneste uitzondering is org.springframework.beans.factory.BeanIsAbstractException: fout bij het maken van bean met de naam 'beanA': de definitie van de bonen is abstract

8. Conclusie

Aan het einde van dit artikel zouden we een duidelijke kaart moeten hebben om door de verscheidenheid aan oorzaken en problemen te navigeren die kunnen leiden tot een BeanCreationException in het voorjaar, evenals een goed begrip van hoe al deze problemen kunnen worden opgelost.

De implementatie van alle uitzonderingsvoorbeelden is te vinden in het github-project - dit is een op Eclipse gebaseerd project, dus het moet gemakkelijk te importeren en uit te voeren zijn zoals het is.