Spring BeanCreationException

Spring BeanCreationException

1. Überblick

In diesem Artikel diskutieren wir dieSpring org.springframework.beans.factory.BeanCreationException - dies ist eine sehr häufige Ausnahme, die ausgelöst wird, wennBeanFactory Beans der Bean-Definitionen erstellt und auf ein Problem stößt. In diesem Artikel werden die häufigsten Ursachen dieser Ausnahme zusammen mit der Lösung erläutert.

Weitere Lektüre:

Einführung in die Inversion von Control und Dependency Injection mit Spring

Eine kurze Einführung in die Konzepte von Inversion of Control und Dependency Injection, gefolgt von einer einfachen Demonstration mit dem Spring Framework

Read more

BeanNameAware- und BeanFactoryAware-Schnittstellen im Frühjahr

Schauen Sie sich im Frühjahr die Arbeit mit den Schnittstellen BeanNameAware und BeanFactoryAware an.

Read more

Spring 5 Functional Bean Registration

In Spring 5 erfahren Sie, wie Sie Beans mithilfe des funktionalen Ansatzes registrieren.

Read more

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

Die bei weitem häufigste Ursache fürBeanCreationException ist Spring, der versucht,inject a bean that doesn’t exist im Kontext zu verwenden.

Zum Beispiel versuchtBeanA,BeanB zu injizieren:

@Component
public class BeanA {

    @Autowired
    private BeanB dependency;
    ...
}

Wenn im Kontext keinBeanB gefunden wird, wird die folgende Ausnahme ausgelöst (Fehler beim Erstellen der Bean):

Error creating bean with name 'beanA': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private org.example.web.BeanB org.example.web.BeanA.dependency;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [org.example.web.BeanB] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Um diese Art von Problem zu diagnostizieren, stellen Sie zunächst sicher, dass die Bean deklariert ist:

  • entweder in einer XML-Konfigurationsdatei mit dem Element<bean />

  • oder in einer Java@Configuration-Klasse über die@Bean-Annotation

  • oder ist mit folgenden Anmerkungen versehen:@Component,@Repository,@Service,@Controller, und das Scannen von Klassenpfaden ist für dieses Paket aktiv

Überprüfen Sie auch, ob die Konfigurationsdateien oder Klassen tatsächlich von Spring erfasst und in den Hauptkontext geladen werden.

Weitere Lektüre:

Einführung in die Inversion von Control und Dependency Injection mit Spring

Eine kurze Einführung in die Konzepte von Inversion of Control und Dependency Injection, gefolgt von einer einfachen Demonstration mit dem Spring Framework

Read more

BeanNameAware- und BeanFactoryAware-Schnittstellen im Frühjahr

Schauen Sie sich im Frühjahr die Arbeit mit den Schnittstellen BeanNameAware und BeanFactoryAware an.

Read more

Spring 5 Functional Bean Registration

In Spring 5 erfahren Sie, wie Sie Beans mithilfe des funktionalen Ansatzes registrieren.

Read more

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

Eine andere ähnliche Ursache für die Bean-Erstellungsausnahme ist Spring, der versucht, eine Bean nach Typ - nämlich nach ihrer Schnittstelle - zu injizieren undtwo or more bean implementing that interface im Kontext zu finden.

Beispielsweise implementierenBeanB1 undBeanB2 beide dieselbe Schnittstelle:

@Component
public class BeanB1 implements IBeanB { ... }
@Component
public class BeanB2 implements IBeanB { ... }

@Component
public class BeanA {

    @Autowired
    private IBeanB dependency;
    ...
}

Dies führt dazu, dass die Springbohnenfabrik die folgende Ausnahme auslöst:

Error creating bean with name 'beanA': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private org.example.web.IBeanB org.example.web.BeanA.b;
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [org.example.web.IBeanB] is defined:
expected single matching bean but found 2: beanB1,beanB2

4. Ursache:org.springframework.beans.BeanInstantiationException

4.1. Benutzerdefinierte Ausnahme

Als nächstes folgt einbean that throws an exception during its creation process; Ein vereinfachtes Beispiel, um das Problem leicht zu veranschaulichen und zu verstehen, löst eine Ausnahme im Konstruktor der Bean aus:

@Component
public class BeanA {

    public BeanA() {
        super();
        throw new NullPointerException();
    }
    ...
}

Wie erwartet führt dies zu einem schnellen Ausfall des Frühlings mit der folgenden Ausnahme:

Error creating bean with name 'beanA' defined in file [...BeanA.class]:
Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException:
Could not instantiate bean class [org.example.web.BeanA]:
Constructor threw exception;
nested exception is java.lang.NullPointerException

4.2. java.lang.InstantiationException

Ein weiteres mögliches Vorkommen vonBeanInstantiationException ist das Definieren einer abstrakten Klasse als Bean in XML. Dies muss in XML erfolgen, da dies in einer Java @ Configuration-Datei nicht möglich ist und beim Scannen von Klassenpfaden die abstrakte Klasse ignoriert wird:

@Component
public abstract class BeanA implements IBeanA { ... }

Und die XML-Definition der Bean:

Dieses Setup führt zu einer ähnlichen Ausnahme:

org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'beanA' defined in class path resource [beansInXml.xml]:
Instantiation of bean failed;
nested exception is org.springframework.beans.BeanInstantiationException:
Could not instantiate bean class [org.example.web.BeanA]:
Is it an abstract class?;
nested exception is java.lang.InstantiationException

4.3. java.lang.NoSuchMethodException

Wenn eine Bean keinen Standardkonstruktor hat und Spring versucht, sie durch Suchen nach diesem Konstruktor zu instanziieren, führt dies zu einer Laufzeitausnahme. beispielsweise:

@Component
public class BeanA implements IBeanA {

    public BeanA(final String name) {
        super();
        System.out.println(name);
    }
}

Wenn diese Bean vom Classpath-Scan-Mechanismus erfasst wird, tritt der folgende Fehler auf:

Error creating bean with name 'beanA' defined in file [...BeanA.class]: Instantiation of bean failed;
nested exception is org.springframework.beans.BeanInstantiationException:
Could not instantiate bean class [org.example.web.BeanA]:
No default constructor found;
nested exception is java.lang.NoSuchMethodException: org.example.web.BeanA.()

Eine ähnliche Ausnahme, die jedoch schwieriger zu diagnostizieren ist, kann auftreten, wenn die Spring-Abhängigkeiten vom Klassenpfad nicht diesame version haben. Diese Art der Versionsinkompatibilität kann aufgrund von API-Änderungen zu einemNoSuchMethodException führen. Die Lösung für ein solches Problem besteht darin, sicherzustellen, dass alle Spring-Bibliotheken im Projekt genau die gleiche Version haben.

5. Ursache:org.springframework.beans.NotWritablePropertyException

Eine weitere Möglichkeit besteht darin, eine Bean -BeanA - mit Bezug auf eine andere Bean -BeanB - zu definieren, ohne die entsprechende Setter-Methode inBeanA zu haben:

@Component
public class BeanA {
    private IBeanB dependency;
    ...
}
@Component
public class BeanB implements IBeanB { ... }

Und die Spring XML-Konfiguration:


    

Auch dies istcan only occur in XML Configuration, da der Compiler bei Verwendung von Java@Configuration die Reproduktion dieses Problems unmöglich macht.

Um dieses Problem zu lösen, muss der Setter natürlich fürIBeanB hinzugefügt werden:

@Component
public class BeanA {
    private IBeanB dependency;

    public void setDependency(final IBeanB dependency) {
        this.dependency = dependency;
    }
}

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

Diese Ausnahme wird ausgelöst, wennSpring cannot load the class of the defined bean - dies kann auftreten, wenn die Spring XML-Konfiguration eine Bean enthält, die einfach keine entsprechende Klasse hat. Wenn beispielsweise die KlasseBeanZnicht vorhanden ist, führt die folgende Definition zu einer Ausnahme:

Die Hauptursache fürClassNotFoundException und die vollständige Ausnahme in diesem Fall ist:

nested exception is org.springframework.beans.factory.BeanCreationException:
...
nested exception is org.springframework.beans.factory.CannotLoadBeanClassException:
Cannot find class [org.example.web.BeanZ] for bean with name 'beanZ'
defined in class path resource [beansInXml.xml];
nested exception is java.lang.ClassNotFoundException: org.example.web.BeanZ

7. Kinder vonBeanCreationException

7.1. Dieorg.springframework.beans.factory.BeanCurrentlyInCreationException

Eine der Unterklassen vonBeanCreationException istBeanCurrentlyInCreationException; Dies tritt normalerweise bei Verwendung der Konstruktorinjektion auf - beispielsweise bei zirkulären Abhängigkeiten:

@Component
public class BeanA implements IBeanA {
    private IBeanB beanB;

    @Autowired
    public BeanA(final IBeanB beanB) {
        super();
        this.beanB = beanB;
    }
}
@Component
public class BeanB implements IBeanB {
    final IBeanA beanA;

    @Autowired
    public BeanB(final IBeanA beanA) {
        super();
        this.beanA = beanA;
    }
}

Spring kann ein solches Verdrahtungsszenario nicht lösen, und das Endergebnis ist:

org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'beanA':
Requested bean is currently in creation: Is there an unresolvable circular reference?

Die vollständige Ausnahme ist sehr ausführlich:

org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'beanA' defined in file [...BeanA.class]:
Unsatisfied dependency expressed through constructor argument with index 0
of type [org.example.web.IBeanB]: :
Error creating bean with name 'beanB' defined in file [...BeanB.class]:
Unsatisfied dependency expressed through constructor argument with index 0
of type [org.example.web.IBeanA]: :
Error creating bean with name 'beanA': Requested bean is currently in creation:
Is there an unresolvable circular reference?;
nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'beanA':
Requested bean is currently in creation:
Is there an unresolvable circular reference?;
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'beanB' defined in file [...BeanB.class]:
Unsatisfied dependency expressed through constructor argument with index 0
of type [org.example.web.IBeanA]: :
Error creating bean with name 'beanA':
Requested bean is currently in creation:
Is there an unresolvable circular reference?;
nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'beanA':
Requested bean is currently in creation: Is there an unresolvable circular reference?

7.2. Dieorg.springframework.beans.factory.BeanIsAbstractException

Diese Instanziierungsausnahme kann auftreten, wenn die Bean Factory versucht, eine als abstrakt deklarierte Bean abzurufen und zu instanziieren. beispielsweise:

public abstract class BeanA implements IBeanA {
   ...
}

In der XML-Konfiguration deklariert als:

Wenn wir nun versuchen,retrieve BeanA from the Spring Context by name zu erreichen - zum Beispiel beim Instanziieren einer anderen Bean:

@Configuration
public class Config {
    @Autowired
    BeanFactory beanFactory;

    @Bean
    public BeanB beanB() {
        beanFactory.getBean("beanA");
        return new BeanB();
    }
}

Dies führt zu der folgenden Ausnahme:

org.springframework.beans.factory.BeanIsAbstractException:
Error creating bean with name 'beanA': Bean definition is abstract

Und das vollständige Ausnahmestacktrace:

org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'beanB' defined in class path resource
[org/example/spring/config/WebConfig.class]: Instantiation of bean failed;
nested exception is org.springframework.beans.factory.BeanDefinitionStoreException:
Factory method
[public org.example.web.BeanB org.example.spring.config.WebConfig.beanB()] threw exception;
nested exception is org.springframework.beans.factory.BeanIsAbstractException:
Error creating bean with name 'beanA': Bean definition is abstract

8. Fazit

Am Ende dieses Artikels sollten wir eine übersichtliche Übersicht über die verschiedenen Ursachen und Probleme haben, die im Frühjahr zu einemBeanCreationExceptionführen können, sowie einen guten Überblick darüber, wie all diese Probleme behoben werden können.

Die Implementierung aller Ausnahmebeispiele finden Sie inthe github project - dies ist ein Eclipse-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein.