1. 概述
本文将深入探讨 Spring 中的 org.springframework.beans.factory.BeanCreationException
异常。这是 Spring 在根据 Bean 定义创建对象时遇到问题抛出的常见异常。我们将分析导致该异常的典型原因及解决方案,帮你快速定位并修复问题。
2. 原因:NoSuchBeanDefinitionException
最常见的原因是 Spring 尝试注入上下文中不存在的 Bean。例如 BeanA
试图注入 BeanB
:
@Component
public class BeanA {
@Autowired
private BeanB dependency;
...
}
如果上下文中找不到 BeanB
,会抛出以下异常:
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)}
排查步骤: ✅ 检查 Bean 是否已声明:
- XML 配置中使用
<bean />
元素 - Java
@Configuration
类中使用@Bean
注解 - 使用
@Component
/@Repository
/@Service
/@Controller
注解且包扫描已启用
✅ 确认 Spring 已加载配置文件/类到主上下文
3. 原因:NoUniqueBeanDefinitionException
当 Spring 按类型注入时,发现多个实现同一接口的 Bean 会触发此异常。例如 BeanB1
和 BeanB2
都实现 IBeanB
:
@Component
public class BeanB1 implements IBeanB { ... }
@Component
public class BeanB2 implements IBeanB { ... }
@Component
public class BeanA {
@Autowired
private IBeanB dependency;
...
}
异常信息:
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. 原因:BeanInstantiationException
4.1 自定义异常
Bean 在创建过程中抛出异常会导致此问题。简单示例:在构造函数中抛出异常:
@Component
public class BeanA {
public BeanA() {
super();
throw new NullPointerException();
}
...
}
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
在 XML 中将抽象类定义为 Bean 会触发此异常(Java 配置无法定义抽象类 Bean):
@Component
public abstract class BeanA implements IBeanA { ... }
XML 配置:
<bean id="beanA" class="com.baeldung.web.BeanA" />
异常信息:
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
Bean 没有默认构造函数且 Spring 尝试通过默认构造函数实例化时:
@Component
public class BeanA implements IBeanA {
public BeanA(final String name) {
super();
System.out.println(name);
}
}
异常信息:
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>()
⚠️ 版本冲突踩坑:Spring 依赖版本不一致也可能导致 NoSuchMethodException
,需确保所有 Spring 库版本完全相同。
5. 原因:NotWritablePropertyException
在 XML 配置中为 BeanA
注入 BeanB
,但 BeanA
缺少对应的 setter 方法:
@Component
public class BeanA {
private IBeanB dependency;
...
}
@Component
public class BeanB implements IBeanB { ... }
XML 配置:
<bean id="beanA" class="com.baeldung.web.BeanA">
<property name="beanB" ref="beanB" />
</bean>
此问题仅发生在 XML 配置中(Java 配置在编译期就会报错)。解决方案:添加 setter 方法:
@Component
public class BeanA {
private IBeanB dependency;
public void setDependency(final IBeanB dependency) {
this.dependency = dependency;
}
}
6. 原因:CannotLoadBeanClassException
当 Spring 无法加载 Bean 定义对应的类时抛出此异常。例如 XML 中定义了不存在的类 BeanZ
:
<bean id="beanZ" class="com.baeldung.web.BeanZ" />
异常信息:
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. BeanCreationException 的子类异常
7.1 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;
}
}
异常信息:
org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'beanA':
Requested bean is currently in creation: Is there an unresolvable circular reference?
完整异常信息非常冗长,核心提示:Is there an unresolvable circular reference?
7.2 BeanIsAbstractException
当 BeanFactory 尝试实例化声明为 abstract 的 Bean 时:
public abstract class BeanA implements IBeanA {
...
}
XML 配置:
<bean id="beanA" abstract="true" class="com.baeldung.web.BeanA" />
如果尝试从上下文获取该 Bean:
@Configuration
public class Config {
@Autowired
BeanFactory beanFactory;
@Bean
public BeanB beanB() {
beanFactory.getBean("beanA");
return new BeanB();
}
}
异常信息:
org.springframework.beans.factory.BeanIsAbstractException:
Error creating bean with name 'beanA': Bean definition is abstract
8. 总结
本文系统分析了 Spring 中 BeanCreationException
的各种诱因及解决方案:
- 依赖 Bean 不存在(
NoSuchBeanDefinitionException
) - 依赖 Bean 不唯一(
NoUniqueBeanDefinitionException
) - Bean 实例化失败(
BeanInstantiationException
) - 属性注入失败(
NotWritablePropertyException
) - 类加载失败(
CannotLoadBeanClassException
) - 循环依赖(
BeanCurrentlyInCreationException
) - 抽象 Bean 实例化(
BeanIsAbstractException
)
掌握这些常见场景的排查方法,能帮你快速定位并解决 Spring 应用中的 Bean 创建问题。所有示例代码可在 GitHub 项目 中找到(基于 Eclipse,可直接导入运行)。