Spring中常见的bean创建异常

1. 概述
    本次我们将讨论在spring中BeanFactory创建bean实例时经常遇到的异常
org.springframework.beans.factory.BeanCreationException,下面我们将讨论并再现这些异常,同时给出解决方案。

2. Cause:org.springframework.beans.factory.NoSuchBeanDefinitionException
    到目前为止最常见的导致BeanCreationException 莫过于注入一个上下文中不存在的bean,既容器中中找不到该@Resource的值
  例如:BeanA尝试注入BeanB

@Component
public class BeanA { @Autowired
private BeanB dependency;
...
}
如果spring上下文中不存在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 org.baeldung.web.BeanB org.baeldung.web.BeanA.dependency;
  nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
  No qualifying bean of type [org.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 / >元素
    或通过@bean注释Java @ configuration类
    或注释:@Component,@Repository,@Service,@Controller和类路径是否扫描包中。
  同时检查配置文件或类文件是否真的已经被spring装载到上下文中。

3. Cause:org.springframework.beans.factory.NoUniqueBeanDefinitionException
另一个比较类似的异常情况,当你尝试让spring使用接口名来时创建一个bean时,但是发现它有两个或多个实现
  例如:BeanB1 和BeanB2都实现了同一个接口

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

  这将导致BeanFactory抛出一下异常:

  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.baeldung.web.IBeanB org.baeldung.web.BeanA.b;
  nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
  No qualifying bean of type [org.baeldung.web.IBeanB] is defined:
  expected single matching bean but found 2: beanB1,beanB2

4. Cause:org.springframework.beans.BeanInstantiationException

4.1. Custom Exception

下面例子是抛出在其创建过程异常;简化的样例很容易体现和理解问题出现构造函数中,并抛出一个异常:

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

4.2. java.lang.InstantiationException

另一种可能发生BeanInstantiationException是在xml配置中使用抽象类定义bean。
这种只可能发生在xml配置文件中,
因为没有办法在Java@Configuration文件和classpath扫描会忽略抽象类来做到这一点:

@Component
public abstract class BeanA implements IBeanA { ... }
<bean id="beanA" class="org.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 [org.baeldung.web.BeanA]:
Is it an abstract class?;
nested exception is java.lang.InstantiationException

4.3. java.lang.NoSuchMethodException

如果一个bean类没有默认的构造方法,spring在创建bean实例时将会抛出如下运行时异常:

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

类似的异常,但难以诊断,当类路径的Spring的依赖并不具有相同的版本,可能会发生异常;这种版本不兼容,可能会导致因API变化的NoSuchMethodException。这种问题的解决方案是确保所有Spring库在该项目中的精确相同的版本。
5. Cause:org.springframework.beans.NotWritablePropertyException
然而,另一种可能性是你定义了一个bean:BeanA同时引用了另一个bean:BeanB但是BeanA中却没有相应的setter方法

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

配置文件

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

此外需要说明的是,这种情况只可能发生在xml配置文件,因为当你使用@Configuration时,spring容器会避免这种情况的发生。
当然,为了解决这个问题,需要为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
当spring加载不到bean对应的类文件时,这种异常将会被抛出。这种情况很有可能发生在当配置文件中的类路径全称找不到对应文件时。

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

抛出ClassNotFoundException的根本原因

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

7. Children of BeanCreationException
7.1. The org.springframework.beans.factory.BeanCurrentlyInCreationException
BeanCurrentlyInCreationException是BeanCreationException的一个子类,经常在发生在错误的使用构造方法注入bean。
例如:循环依赖的情况

@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将不能够解决这种场景,最终导致

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

完整的异常信息非常丰富

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.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 [org.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 [org.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

public abstract class BeanA implements IBeanA {
...
}

在xml配置中声明如下:

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

现在,如果试图从spring上线文中获取BeanA实例,例如:

@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

全部异常栈信息:

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 org.baeldung.web.BeanB org.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 、org.springframework.beans.factory.BeanNotOfRequiredTypeException
由于我之前在实现Dao接口时直接实现了Dao的实现类DaoImpl而不是实现Dao,所以当另一个类实现Dao接口时则会出现异常。
所以下次要使用Dao接口来注入而不是具体的实现类。

Spring中常见的bean创建异常的更多相关文章

  1. spring中整合memcached,以及创建memcache的put和get方法

    spring中整合memcached,以及创建memcache的put和get方法: 1:在项目中导入memcache相关的jar包 2:memcache在spring.xml的配置: 代码: < ...

  2. spring中自动装配bean

    首先用@Component注解类: package soundsystem: import org.springframework.stereotype.Component; @Component p ...

  3. Spring中注解注入bean和配置文件注入bean

    注解的方式确实比手动写xml文件注入要方便快捷很多,省去了很多不必要的时间去写xml文件 按以往要注入bean的时候,需要去配置一个xml,当然也可以直接扫描包体,用xml注入bean有以下方法: & ...

  4. Spring中常见的设计模式——代理模式

    一.代理模式的应用场景 生活中的中介,黄牛,等一系列帮助甲方做事的行为,都是代理模式的体现.代理模式(Proxy Pattern)是指为题对象提供一种代理,以控制对这个对象的访问.代理对象在客户端和目 ...

  5. 【转】Spring 中三种Bean配置方式比较

    今天被问到Spring中Bean的配置方式,很尴尬,只想到了基于XML的配置方式,其他的一时想不起来了,看来Spring的内容还没有完全梳理清楚,见到一篇不错的文章,就先转过来了. 以前Java框架基 ...

  6. Spring 中三种Bean配置方式比较

    今天被问到Spring中Bean的配置方式,很尴尬,只想到了基于XML的配置方式,其他的一时想不起来了,看来Spring的内容还没有完全梳理清楚,见到一篇不错的文章,就先转过来了. 以前Java框架基 ...

  7. Spring中如何向 Bean注入系统属性或环境变量

    [转自] http://unmi.cc/spring-injection-system-properties-env/ 在 Spring 中为 javabean 注入属性文件中的属性值一般人都知道的, ...

  8. Spring中常见的设计模式——单例模式

    一.单例模式的应用场景 单例模式(singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点.J2EE中的ServletContext,ServletCon ...

  9. Spring中常见的设计模式——委派模式

    一.委派模式的定义及应用场景 委派模式(Delegate Pattern)的基本作用是负责任务的调用和分配,跟代理模式很像,可以看做特殊情况下的静态的全权代理,但是代理模式注重过程,而委派模式注重结果 ...

随机推荐

  1. ASP.NET Core 中文文档 第四章 MVC(4.3)过滤器

    原文:Filters 作者:Steve Smith 翻译:刘怡(AlexLEWIS) 校对:何镇汐 ASP.NET MVC 过滤器 可在执行管道的前后特定阶段执行代码.过滤器可以配置为全局有效.仅对控 ...

  2. win10上部署Hadoop-2.7.3——非Cygwin、非虚拟机

    开始接触Hadoop,听人说一般都是在Lunix下部署Hadoop,但是本人Lunix不是很了解,所以Google以下如何在Win10下安装Hadoop(之后再在Lunix下弄),找到不少文章,以下是 ...

  3. Apache Cordova开发Android应用程序——番外篇

    很多天之前就安装了visual studio community 2015,今天闲着么事想试一下Apache Cordova,用它来开发跨平台App.在这之前需要配置N多东西,这里找到了一篇MS官方文 ...

  4. windows 7(32/64位)GHO安装指南(序篇)~

    大家好,本人是高三刚毕业,即将踏入校园的程序猿~我写这篇文章呢,主要是想巩固一下之前对于电脑的基础知识理论,也希望能帮助没有电脑基础的同学能维护一下自己的电脑,要是能帮助女生修电脑那就是更好啦~~哈哈 ...

  5. Spring WebService入门

    Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述.发布.发现.协调和配置这些应用程序,用于开发分布 ...

  6. 我的MYSQL学习心得(十五) 日志

    我的MYSQL学习心得(十五) 日志 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  7. CSharpGL(27)讲讲清楚OpenGL坐标变换

    CSharpGL(27)讲讲清楚OpenGL坐标变换 在理解OpenGL的坐标变换问题的路上,有好几个难点和易错点.且OpenGL秉持着程序难以调试.难点互相纠缠的特色,更让人迷惑.本文依序整理出关于 ...

  8. 学会使用Spring注解

      概述 注释配置相对于 XML 配置具有很多的优势: 它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作.如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 ...

  9. Android开发学习之路-动态高斯模糊怎么做

    什么是高斯模糊? 高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop.GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪 ...

  10. 深入浅出Java三大框架SSH与MVC的设计模式

    现在许许多多的初学者和程序员,都在趋之若鹜地学习Web开发的宝典级框架:Struts2,Spring,Hibernate.似乎这些框架成为了一个人是否精通Java,是否会写J2EE程序的唯一事实标准和 ...