Spring BeanCreationException – Spring的BeanCreationException

最后修改: 2013年 5月 25日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll discuss the Spring org.springframework.beans.factory.BeanCreationException. It’s a very common exception thrown when the BeanFactory creates beans of the bean definitions, and encounteres a problem. This article will explore the most common causes of this exception, along with the solutions.

在本教程中,我们将讨论Spring org.springframework.beans.factory.BeanCreationException.这是一个非常常见的异常,当BeanFactory创建bean定义的bean时,遇到了问题。本文将探讨造成这种异常的最常见原因,以及解决办法。

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

2.原因 org.springframework.beans.factory.NoSuchBeanDefinitionException

By far, the most common cause of the BeanCreationException is Spring trying to inject a bean that doesn’t exist in the context.

到目前为止,导致BeanCreationException的最常见原因是Spring试图注入一个在上下文中不存在的bean

For example, BeanA is trying to inject BeanB:

例如,BeanA正试图注入BeanB

@Component
public class BeanA {

    @Autowired
    private BeanB dependency;
    ...
}

If a BeanB isn’t found in the context, then the following exception will be thrown (Error Creating Bean):

如果在上下文中没有找到BeanB,那么将抛出以下异常(Error Creating 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)}

To diagnose this type of issue, we’ll first make sure the bean is declared:

为了诊断这种类型的问题,我们首先要确保Bean被声明。

  • either in an XML configuration file using the <bean /> element
  • or in a Java @Configuration class via the @Bean annotation
  • or is annotated with @Component, @Repository, @Service, @Controller, and classpath scanning is active for that package

We’ll also check that Spring actually picks up the configuration files or classes, and loads them into the main context.

我们还将检查Spring是否真的拾取了配置文件或类,并将它们加载到主上下文中。

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

3.原因 org.springframework.beans.factory.NoUniqueBeanDefinitionException

Another similar cause for the bean creation exception is Spring trying to inject a bean by type, namely by its interface, and finding two or more beans implementing that interface in the context.

另一个导致Bean创建异常的类似原因是Spring试图按类型(即按接口)注入Bean,并在上下文中发现两个或多个实现该接口的Bean

For example, BeanB1 and BeanB2 both implement the same interface:

例如,BeanB1BeanB2都实现了同一个接口。

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

@Component
public class BeanA {

    @Autowired
    private IBeanB dependency;
    ...
}

This will lead to the following exception being thrown by the Spring bean factory:

这将导致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.原因 org.springframework.beans.BeanInstantiationException

4.1. Custom Exception

4.1.自定义异常

Next in line is a bean that throws an exception during its creation process. A simplified example to easily understand the problem is throwing an exception in the constructor of the bean:

接下来是一个在创建过程中抛出异常的bean。为了便于理解这个问题,一个简化的例子是在bean的构造函数中抛出一个异常。

@Component
public class BeanA {

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

As expected, this will lead to Spring failing fast with the following exception:

正如预期的那样,这将导致Spring快速失败,出现以下异常。

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

4.2.java.lang.InstantiationException

Another possible occurence of the BeanInstantiationException is defining an abstract class as a bean in XML; this has to be in XML because there’s no way to do it in a Java @Configuration file, and classpath scanning will ignore the abstract class:

BeanInstantiationException的另一个可能出现的情况是在XML中把抽象类定义为Bean;这必须在XML中进行,因为没有办法在Java @Configuration文件中进行,而且classpath扫描会忽略这个抽象类。

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

Here’s the XML definition of the bean:

下面是这个bean的XML定义。

<bean id="beanA" class="com.baeldung.web.BeanA" />

This setup will result in a similar exception:

这种设置将导致类似的异常。

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

4.3.java.lang.NoSuchMethodException

If a bean has no default constructor, and Spring tries to instantiate it by looking for that constructor, this will result in a runtime exception:

如果一个Bean没有默认的构造函数,而Spring试图通过寻找该构造函数来实例化它,这将导致一个运行时异常。

@Component
public class BeanA implements IBeanA {

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

When the classpath scanning mechanism picks up this bean, the failure will be:

当classpath扫描机制捡到这个bean时,故障将是。

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

A similar exception, but harder to diagnose, may occur when the Spring dependencies on the classpath don’t have the same version. This kind of version incompatibility may result in a NoSuchMethodException because of API changes. The solution to such a problem is to make sure all Spring libraries have the exact same version in the project.

当classpath上的Spring依赖项没有相同的版本时,可能会出现类似的异常,但更难诊断。这种版本不兼容可能会因为API变化而导致NoSuchMethodException。解决此类问题的方法是确保项目中所有Spring库的版本完全相同。

5. Cause: org.springframework.beans.NotWritablePropertyException

5.原因 org.springframework.beans.NotWritablePropertyException

Yet another possiblity is defining a bean, BeanA, with a reference to another bean, BeanB, without having the corresponding setter method in BeanA:

然而,另一种可能性是定义一个Bean,BeanA,,并引用另一个Bean,BeanB,,但在BeanA中没有相应的setter方法。

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

Here’s  the Spring XML Configuration:

这里是Spring的XML配置。

<bean id="beanA" class="com.baeldung.web.BeanA">
    <property name="beanB" ref="beanB" />
</bean>

Again, this can only occur in XML Configuration because when using Java @Configuration, the compiler will make this issue impossible to reproduce.

同样,这种情况只能在XML配置中发生,因为当使用Java @Configuration时,编译器会使这个问题无法重现。

Of course, in order to solve this issue, we need to add the setter for IBeanB:

当然,为了解决这个问题,我们需要为IBeanB添加setter。

@Component
public class BeanA {
    private IBeanB dependency;

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

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

6.原因 org.springframework.beans.factory.CannotLoadBeanClassException

Spring throws this exception when it can’t load the class of the defined bean. This may occur if the Spring XML Configuration contains a bean that simply doesn’t have a corresponding class. For example, if class BeanZ doesn’t exist, the following definition will result in an exception:

当Spring无法加载所定义的Bean的类时,它会抛出这个异常。如果Spring XML配置中包含的Bean没有相应的类,就会出现这种情况。例如,如果BeanZ类不存在,下面的定义将导致一个异常。

<bean id="beanZ" class="com.baeldung.web.BeanZ" />

The root cause of the ClassNotFoundException and the full exception in this case is:

在这种情况下,ClassNotFoundException的根本原因和完整的异常是。

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. Children of BeanCreationException

7.BeanCreationException的子女

7.1. The org.springframework.beans.factory.BeanCurrentlyInCreationException

7.1.org.springframework.beans.factory.BeanCurrentlyInCreationException

One of the subclasses of BeanCreationException is the BeanCurrentlyInCreationException. This usually occurs when using constructor injection, for example, in a case of circular dependencies:

BeanCreationException的一个子类是BeanCurrentlyInCreationException。这通常发生在使用构造函数注入时,例如,在循环依赖的情况下。

@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 won’t be able to resolve this kind of wiring scenario and the end result will be:

Spring无法解决这种接线情况,最终的结果将是。

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

The full exception is very verbose:

完整的异常是非常冗长的。

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. The org.springframework.beans.factory.BeanIsAbstractException

7.2.org.springframework.beans.factory.BeanIsAbstractException

This instantiation exception may occur when the Bean Factory attempts to retrieve and instantiate a bean that was declared as abstract:

当Bean Factory试图检索和实例化一个被声明为抽象的Bean时,可能会发生这种实例化异常。

public abstract class BeanA implements IBeanA {
   ...
}

We declare it in the XML Configuration as:

我们在XML配置中声明它为。

<bean id="beanA" abstract="true" class="com.baeldung.web.BeanA" />

If we try to retrieve BeanA from the Spring Context by name, like when instantiating another bean:

如果我们试图通过名字从Spring Context中检索BeanA比如在实例化另一个Bean时。

@Configuration
public class Config {
    @Autowired
    BeanFactory beanFactory;

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

This will result in the following exception:

这将导致以下异常。

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

And the full exception stacktrace:

还有完整的异常堆栈跟踪。

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

8.结论

In this article, we learned how to navigate the variety of causes and problems that may lead to a BeanCreationException in Spring, as well as developed a good grasp on how to fix all of these problems.

在这篇文章中,我们学习了如何驾驭可能导致Spring中出现BeanCreationException的各种原因和问题,以及对如何修复所有这些问题的良好把握。

The implementation of all the exception examples can be found in the github project. This is an Eclipse based project, so it should be easy to import and run as it is.

可以在github项目中找到所有异常示例的实现。这是一个基于Eclipse的项目,所以它应该很容易导入并按原样运行。