Spring BeanCreationException

1. Vue d'ensemble

Dans cet article, nous discutons de l' exception Spring org.springframework.beans.factory.BeanCreationException - il s'agit d'une exception très courante levée lorsque BeanFactory crée des beans des définitions de bean et rencontre un problème. L'article abordera les causes les plus courantes de cette exception ainsi que la solution.

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

La cause de loin la plus courante de l' exception BeanCreationException est que Spring tente d' injecter un bean qui n'existe pas dans le contexte.

Par exemple, BeanA essaie d'injecter BeanB :

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

Si un BeanB n'est pas trouvé dans le contexte, l'exception suivante sera levée (Erreur lors de la création du 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 com.baeldung.web.BeanB cpm.baeldung.web.BeanA.dependency; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.baeldung.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)}

Pour diagnostiquer ce type de problème, assurez-vous d'abord que le bean est déclaré:

  • soit dans un fichier de configuration XML à l'aide du élément
  • ou dans une classe Java @Configuration via l' annotation @Bean
  • ou est annoté avec: @Component , @Repository , @Service , @Controller et l'analyse de chemin de classe est active pour ce package

Vérifiez également que les fichiers ou classes de configuration sont effectivement récupérés par Spring et chargés dans le contexte principal.

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

Une autre cause similaire pour l'exception de création de bean est que Spring tente d'injecter un bean par type - à savoir par son interface - et trouve deux ou plusieurs bean implémentant cette interface dans le contexte.

Par exemple, BeanB1 et BeanB2 implémentent tous deux la même interface:

@Component public class BeanB1 implements IBeanB { ... } @Component public class BeanB2 implements IBeanB { ... } @Component public class BeanA { @Autowired private IBeanB dependency; ... }

Cela conduira à l'exception suivante lancée par l'usine Spring 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 com.baeldung.web.IBeanB com.baeldung.web.BeanA.b; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.baeldung.web.IBeanB] is defined: expected single matching bean but found 2: beanB1,beanB2

4. Cause: org.springframework.beans.BeanInstantiationException

4.1. Exception personnalisée

Le prochain en ligne est un bean qui lève une exception pendant son processus de création ; un exemple simplifié pour illustrer et comprendre facilement le problème lève une exception dans le constructeur du bean:

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

Comme prévu, cela entraînera un échec rapide de Spring avec l'exception suivante:

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 [com.baeldung.web.BeanA]: Constructor threw exception; nested exception is java.lang.NullPointerException

4.2. java.lang.InstantiationException

Une autre occurrence possible de l' exception BeanInstantiationException consiste à définir une classe abstraite comme un bean dans XML; cela doit être en XML, car il n'y a aucun moyen de le faire dans un fichier Java @Configuration et l'analyse du chemin de classe ignorera la classe abstraite:

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

Et la définition XML du bean:

Cette configuration entraînera une exception similaire:

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 [com.baeldung.web.BeanA]: Is it an abstract class?; nested exception is java.lang.InstantiationException

4.3. java.lang.NoSuchMethodException

Si un bean n'a pas de constructeur par défaut et que Spring essaie de l'instancier en recherchant ce constructeur, cela entraînera une exception d'exécution; par exemple:

@Component public class BeanA implements IBeanA { public BeanA(final String name) { super(); System.out.println(name); } }

Lorsque ce bean est récupéré par le mécanisme d'analyse du chemin de classe, l'échec sera:

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 [com.baeldung.web.BeanA]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.baeldung.web.BeanA.()

Une exception similaire, mais plus difficile à diagnostiquer, peut se produire lorsque les dépendances Spring sur le chemin de classe n'ont pas la même version ; ce type d'incompatibilité de version peut entraîner une exception NoSuchMethodException en raison de modifications de l'API. La solution à un tel problème est de s'assurer que toutes les bibliothèques Spring ont exactement la même version dans le projet.

5. Cause: org.springframework.beans.NotWritablePropertyException

Une autre possibilité est de définir un bean - BeanA - avec une référence à un autre bean - BeanB - sans avoir la méthode setter correspondante dans BeanA :

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

Et la configuration XML Spring:

Là encore, cela ne peut se produire que dans la configuration XML , car lorsque vous utilisez Java @Configuration , le compilateur rendra ce problème impossible à reproduire.

Bien sûr, pour résoudre ce problème, le setter doit être ajouté pour IBeanB :

@Component public class BeanA { private IBeanB dependency; public void setDependency(final IBeanB dependency) { this.dependency = dependency; } }

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

Cette exception est levée lorsque Spring ne peut pas charger la classe du bean défini - cela peut se produire si la configuration XML Spring contient un bean qui n'a tout simplement pas de classe correspondante. Par exemple, si la classe BeanZ n'existe pas, la définition suivante entraînera une exception:

La cause première si ClassNotFoundException et l'exception complète dans ce cas est:

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

7. Enfants de BeanCreationException

7.1. L' exception org.springframework.beans.factory.BeanCurrentlyInCreationException

L'une des sous-classes de BeanCreationException est BeanCurrentlyInCreationException ; cela se produit généralement lors de l'utilisation de l'injection de constructeur - par exemple, dans le cas de dépendances circulaires:

@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 ne pourra pas résoudre ce genre de scénario de câblage et le résultat final sera:

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

L'exception complète est très verbeuse:

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 [com.baeldung.web.IBeanB]: : Error creating bean with name 'beanB' defined in file [...BeanB.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.baeldung.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 [com.baeldung.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. L' exception org.springframework.beans.factory.BeanIsAbstractException

Cette exception d'instanciation peut se produire lorsque Bean Factory tente de récupérer et d'instancier un bean qui a été déclaré comme abstrait; par exemple:

public abstract class BeanA implements IBeanA { ... }

Déclaré dans la configuration XML comme:

Maintenant, si nous essayons de récupérer BeanA à partir du contexte Spring par nom - par exemple lors de l'instanciation d'un autre bean:

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

Cela entraînera l'exception suivante:

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

Et le stacktrace d'exception complet:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beanB' defined in class path resource [org/baeldung/spring/config/WebConfig.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public com.baeldung.web.BeanB com.baeldung.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. Conclusion

À la fin de cet article, nous devrions avoir une carte claire pour parcourir la variété des causes et des problèmes qui peuvent conduire à une BeanCreationException au printemps, ainsi qu'une bonne compréhension de la façon de résoudre tous ces problèmes.

L'implémentation de tous les exemples d'exceptions peut être trouvée dans le projet github - il s'agit d'un projet basé sur Eclipse, il devrait donc être facile à importer et à exécuter tel quel.