摘要:本文译自Eugen Paraschiv文章Spring NoSuchBeanDefinitionException 原文链接: http://www.baeldung.com/spring-nosuchbeandefinitionexception 感谢Eugen Paraschiv对此所做的研究。

概述

在本文中,我将通过实例向你展示Spring 中org.springframework.beans.factory.NoSuchBeanDefinitionException 出现的原因。如果BeanFactory在Spring Context中没有找到bean的实例,就会抛出这个常见的异常。

Cause: No qualifying bean of type […] found for dependency

这个异常的出现一般是因为需要注入的bean未定义
有一个类BeanA.java

package com.csdn.training.model;
@Component
public class BeanA {@Autowiredprivate BeanB beanB;
}

有一个类BeanB.java

package com.csdn.training.service;@Component
public class BeanB {}

配置文件applicationContext.xml

<context:component-scan base-package="com.csdn.training.model"></context:component-scan>

用一个测试类去启动拉起Spring容器:

package com.csdn.test;public class AppTest {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");BeanA beanA = (BeanA) context.getBean("beanA");}
}

自动扫描包路径缺少了BeanB,它和BeanA 不在同一路径下
如果依赖 IBusinessService 在Spring 上下文中没有定义,引导进程报错:No Such Bean Definition Exception.

nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.csdn.training.service.BeanB] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.

Spring会提示:”Expected at least 1 bean which qualifies as autowire candidate for this dependency“(依赖至少有一个备选的bean能被自动注入)
出现异常的原因是IBusinessService 在上下文中不存在:如果bean是通过classpath自动扫描来装配,并且IBusinessService已经正确的加上了注解(@Component,@Repository,@Service,@Controller等),也许是你没有把正确的包路径告诉Spring。

配置文件可以如下配置:

<context:component-scan base-package="com.csdn.training"></context:component-scan>

如果bean不能自动被扫描到,而手动定义却可以识别,那Bean就没有在Spring上下文中定义。

Cause: No qualifying bean of type […] is defined

造成这一异常的原因可能是Spring上下文中存在两个或以上该bean的定义。如果接口IService 有两个实现类 ServiceImplA 和ServiceImplB
接口:IService.java

package com.csdn.training.service;public interface IService {}

两个实现类:ServiceImplA.java

package com.csdn.training.service;import org.springframework.stereotype.Service;
@Service
public class ServiceImplA implements IService {}

ServiceImplB.java

package com.csdn.training.service;import org.springframework.stereotype.Service;
@Service
public class ServiceImplB implements IService {}

如果BeanA 自动注入这一接口,Spring就无法分辨到底注入哪一个实现类:

package com.csdn.training.model;import com.csdn.training.service.IService;
@Component
public class BeanA {    @Autowiredprivate IService serviceImpl;
}

然后,BeanFactory就抛出异常NoSuchBeanDefinitionException
Spring会提示:”expected single matching bean but found 2“(只应该匹配一个bean但是找到了多个)

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [com.csdn.training.service.IService] is defined:
expected single matching bean but found 2: serviceImplA,serviceImplB

上例中,有时你看到的异常信息是NoUniqueBeanDefinitionException,它是NoSuchBeanDefinitionException 它的子类,在Spring 3.2.1中,修正了这一异常,为的是和bean未定义这一异常区分开。

nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.csdn.training.service.IService] is defined: expected single matching bean but found 2: serviceImplA,serviceImplB

解决这一异常可以用注解@Qualifier 来指定想要注入的bean的名字。

package com.csdn.training.model;import com.csdn.training.service.IService;
@Component
public class BeanA {@Autowired@Qualifier("serviceImplA")private IService serviceImpl;
}

修改以后,Spring就可以区分出应该注入那个bean的实例,需要注意的是ServiceImplA的默认实例名称是serviceImplA

Cause: No Bean Named […] is defined

当你通过具体的bean的名字去得到一个bean的实例的时候,如果Spring 没有在上下文中找到这个bean,就会抛出这个异常。

package com.csdn.test;public class AppTest {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");context.getBean("beanX");}
}

这个例子中,没有一个bean被定义成 “beanX”,就会抛出如下异常:
Spring会提示:”No bean named XXX is defined” (没有找到一个名叫XXX的bean)

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'beanX' is defined at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition

Cause: Proxied Beans

如果bean由JDK的动态代理机制所管理,那么代理将不会继承该bean,它只会实现与其相同的接口。因此,如果bean是通过接口注入的,就可以成功注入。如果通过其实现类注入,Spring就无法将bean实例与类关联,因为代理并不真正的继承于类。
出现这一原因,很有可能是因为你使用了Spring的事物,在bean上使用了注解@Transactional
如下,ServiceA注入了ServiceB,这两个service都使用了事物,通过实现类注入bean就不起作用了。
借口IService.java无变化,其实现类加上事物的注解
ServiceImplA.java

package com.csdn.training.service;@Service
@Transactional
public class ServiceImplA implements IService {@Autowiredprivate ServiceImplB serviceImplB;
}

ServiceImplB.java

package com.csdn.training.service;@Service
@Transactional
public class ServiceImplB implements IService {}

如果改成通过接口注入,就可以:

ServiceImpl.java

package com.csdn.training.service;@Service
@Transactional
public class ServiceImplA implements IService {@Autowired@Qualifier("serviceImplB")private IService serviceImplB;
}

结论

本文通过几个小例子,分析了NoSuchBeanDefinitionException 用了这一异常可能出现的情形,对于我们在实际开发过程中定位错误提供了一定的参考。
原文为英文版,我在原文的基础上稍作改动,但又尽量保持原文的精髓,如果对译文有异议,欢迎指正。

Spring NoSuchBeanDefinitionException原因分析相关推荐

  1. spring源码分析之spring-core总结篇

    1.spring-core概览 spring-core是spring框架的基石,它为spring框架提供了基础的支持. spring-core从源码上看,分为6个package,分别是asm,cgli ...

  2. Hasor【付诸实践 01】低代码框架 DataQL 聚合查询引擎 SQL执行器报错 Query dialect missing 原因分析及解决(针对GreenPlum数据库)

    1.报错说明 在本地搭建了两个平台,hasor核心依赖的版本是一致的, 连接的都是GreenPlum数据库 ,且执行的是相同的DataQL语句: <!--hasor核心依赖[是老平台接入,由于兼 ...

  3. 【Spring源码分析】Bean加载流程概览

    代码入口 之前写文章都会啰啰嗦嗦一大堆再开始,进入[Spring源码分析]这个板块就直接切入正题了. 很多朋友可能想看Spring源码,但是不知道应当如何入手去看,这个可以理解:Java开发者通常从事 ...

  4. 【spring源码分析】IOC容器初始化(二)

    前言:在[spring源码分析]IOC容器初始化(一)文末中已经提出loadBeanDefinitions(DefaultListableBeanFactory)的重要性,本文将以此为切入点继续分析. ...

  5. 接口方法上的注解无法被@Aspect声明的切面拦截的原因分析

    转载自  接口方法上的注解无法被@Aspect声明的切面拦截的原因分析 前言 在Spring中使用MyBatis的Mapper接口自动生成时,用一个自定义的注解标记在Mapper接口的方法中,再利用@ ...

  6. @Autowired报错的4种解决方案和原因分析!

    作者 | 王磊 来源 | Java中文社群(ID:javacn666) 转载请联系授权(微信ID:GG_Stone) 上图的报错信息相信大部分程序员都遇到过,奇怪的是虽然代码报错,但丝毫不影响程序的正 ...

  7. beaninfo详解源码解析 java_【Spring源码分析】Bean加载流程概览

    代码入口 之前写文章都会啰啰嗦嗦一大堆再开始,进入[Spring源码分析]这个板块就直接切入正题了. 很多朋友可能想看Spring源码,但是不知道应当如何入手去看,这个可以理解:Java开发者通常从事 ...

  8. 空指针异常的原因分析

    空指针异常的原因分析: 1.当一个对象不存在时又调用其方法会产生异常obj.method() // obj对象不存在 2. 调用空对象的方法时就会抛出 NullPointerException 空指针 ...

  9. Tomcat内存溢出原因分析

    Tomcat内存溢出的原因  在生产环境中tomcat内存设置不好很容易出现内存溢出.造成内存溢出是不一样的,当然处理方式也不一样. 这里根据平时遇到的情况和相关资料进行一个总结.常见的一般会有下面三 ...

最新文章

  1. 智源出品 | 超大规模智能模型产业发展报告(附下载)
  2. List集合与List的子类
  3. BZOJ 3329 Xorequ (数位DP、矩阵乘法)
  4. SQL语句 SELECT LIKE用法详解
  5. J2EE 第二阶段项目之编写代码(六)
  6. MyEclipse下Struts2配置使用和Ajax、JSON的配合
  7. jQuery学习之五---效果
  8. 如何将自己的网站分享到QQ空间,微信,微博等等。
  9. Taints和Tolerations联用,将pod部署到k8s的master节点
  10. 如何用python计算数独_用python解决数独
  11. netbean 快捷键
  12. Echarts饼图无法切换漏斗图问题处理
  13. 作文以记之 ~ 完全平方数
  14. P5459 [BJOI2016]回转寿司 (cdq分治)
  15. ICLOUD储存空间要升级吗_iPhone正确使用iCloud云空间,拒绝已满
  16. I - Simpsons’ Hidden Talents
  17. 我手机计算机屏幕是黑色的,原来如此 手机屏幕边缘的黑边是什么呢?
  18. 汇编语言:以GRADE为首地址的10个字的数组中保存有学生成绩。建立一个10个字的RNAK 数组,并根据GRADE中的学生成绩将学生名次填入RANK数组中
  19. 通过网页api接口获取网页数据
  20. RP Fiber Power 光孤子自频移效应

热门文章

  1. 内温的整体优先效应实验_第四章 知觉10.ppt
  2. 移动端 - adb shell常用命令
  3. 安凯AK3918E加载mtk7601驱动不能ifconfig wlan0 down
  4. 基于卷积神经网络的高光谱分类 CNN+高光谱+印度松数据集
  5. 一枚程序员的跑步之路
  6. C++PrimerPlus 第六章 分支语句和逻辑运算符(复习题)
  7. 详解等保三级7大关键点
  8. Rust Tokio hyper 协程下载文件工具
  9. C++编程笔记:使用WinHTTP实现HTTP访问(解决接收UTF8数据乱码问题)
  10. 想进BAT?这些测试面试题助你一臂之力(附答案)