Spring BeanCreationException

Spring BeanCreationException

1. Vue d'ensemble

Dans cet article, nous discutons desSpring org.springframework.beans.factory.BeanCreationException - il s'agit d'une exception très courante lancée lorsqueBeanFactory crée des beans des définitions de bean et rencontre un problème. L'article discutera des causes les plus courantes de cette exception avec la solution.

Lectures complémentaires:

Introduction à l'inversion du contrôle et injection de dépendance avec ressort

Une introduction rapide aux concepts d'inversion de contrôle et d'injection de dépendance, suivie d'une démonstration simple à l'aide du framework Spring

Read more

Interfaces BeanNameAware et BeanFactoryAware au printemps

Examinez comment utiliser les interfaces BeanNameAware et BeanFactoryAware dans Spring.

Read more

Enregistrement du bean fonctionnel Spring 5

Voyez comment enregistrer des haricots en utilisant l’approche fonctionnelle du printemps 5.

Read more

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

La cause de loin la plus courante desBeanCreationException est que Spring essaye deinject a bean that doesn’t exist dans le contexte.

Par exemple,BeanA tente d'injecterBeanB:

@Component
public class BeanA {

    @Autowired
    private BeanB dependency;
    ...
}

Si unBeanB 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 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)}

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

  • soit dans un fichier de configuration XML utilisant l'élément<bean />

  • ou dans une classe Java@Configuration via l'annotation@Bean

  • ou est annoté avec:@Component,@Repository,@Service,@Controller et l'analyse du chemin de classe est active pour ce package

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

Lectures complémentaires:

Introduction à l'inversion du contrôle et injection de dépendance avec ressort

Une introduction rapide aux concepts d'inversion de contrôle et d'injection de dépendance, suivie d'une démonstration simple à l'aide du framework Spring

Read more

Interfaces BeanNameAware et BeanFactoryAware au printemps

Examinez comment utiliser les interfaces BeanNameAware et BeanFactoryAware dans Spring.

Read more

Enregistrement du bean fonctionnel Spring 5

Voyez comment enregistrer des haricots en utilisant l’approche fonctionnelle du printemps 5.

Read more

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 trouvetwo or more bean implementing that interface dans le contexte.

Par exemple,BeanB1 etBeanB2 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 entraînera l'exception suivante de la part de l'usine de haricots Spring:

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. Cause:org.springframework.beans.BeanInstantiationException

4.1. Exception personnalisée

Le suivant en ligne est unbean that throws an exception during its creation process; 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 l'échec rapide de Spring, à l'exception de 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 [org.example.web.BeanA]:
Constructor threw exception;
nested exception is java.lang.NullPointerException

4.2. java.lang.InstantiationException

Une autre occurrence possible desBeanInstantiationException est de définir une classe abstraite comme un bean en 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 haricot:

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 [org.example.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 tente de l'instancier en le recherchant, cela provoquera 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 détecté par le mécanisme d'analyse des classpath, l'échec sera le suivant:

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.()

Une exception similaire, mais plus difficile à diagnostiquer, peut se produire lorsque les dépendances Spring sur le chemin de classe n'ont pas lessame version; ce type d'incompatibilité de version peut entraîner unNoSuchMethodException en raison des modifications de l'API. La solution à un tel problème consiste à s’assurer que toutes les bibliothèques Spring ont exactement la même version du 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 dansBeanA:

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

Et la configuration XML de printemps:


    

Encore une fois, cecan only occur in XML Configuration, car lors de l'utilisation de Java@Configuration, le compilateur rendra ce problème impossible à reproduire.

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

@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 lorsqueSpring cannot load the class of the defined bean - 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 classeBeanZ n’existe pas, la définition suivante entraînera une exception:

La cause première si leClassNotFoundException 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 [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. Enfants deBeanCreationException

7.1. Lesorg.springframework.beans.factory.BeanCurrentlyInCreationException

Une des sous-classes deBeanCreationException est leBeanCurrentlyInCreationException; 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 sera pas en mesure de résoudre ce type 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 [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. Lesorg.springframework.beans.factory.BeanIsAbstractException

Cette exception d'instanciation peut se produire lorsque Bean Factory tente d'extraire et d'instancier un bean déclaré comme abstrait. par exemple:

public abstract class BeanA implements IBeanA {
   ...
}

Déclaré dans la configuration XML comme:

Maintenant, si nous essayons deretrieve BeanA from the Spring Context by name - 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 la pile d'exceptions complète:

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. Conclusion

À la fin de cet article, nous devrions avoir une carte claire pour naviguer dans la variété des causes et des problèmes qui peuvent conduire à unBeanCreationException 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 dansthe github project - il s'agit d'un projet basé sur Eclipse, il devrait donc être facile à importer et à exécuter tel quel.