• 摘要:摘要:本文译自EugenParaschiv文章SpringNoSuchBeanDefinitionException原文链接:/2014th7cj/d/file/p/20161012/dv5o0x5koba感谢EugenParaschiv对此所做的研究。概述在本文中,我将通过实例向你展示Spring中org.springframework.beans.factory.NoSuchBeanDefinitionException出现的原因。如果BeanFactory在Spring
    • 摘要:本文译自Eugen Paraschiv文章Spring NoSuchBeanDefinitionException 原文链接: /2014th7cj/d/file/p/20161012/dv5o0x5koba 感谢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 { @Autowired private BeanB beanB; }

      有一个类BeanB.java

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

      配置文件applicationContext.xml

      用一个测试类去启动拉起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。

      配置文件可以如下配置:

      如果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 { @Autowired private 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 { @Autowired private 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源码分析】IOC容器初始化(七)

    前言:在[spring源码分析]IOC容器初始化(六)中分析了从单例缓存中加载bean对象,由于篇幅原因其核心函数 FactoryBeanRegistrySupport#getObjectFromFa ...

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

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

  3. Spring源码分析——BeanFactory体系之抽象类、类分析(二)

    上一篇分析了BeanFactory体系的2个类,SimpleAliasRegistry和DefaultSingletonBeanRegistry——Spring源码分析——BeanFactory体系之 ...

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

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

  5. 【Spring源码分析】原型Bean实例化过程、byName与byType及FactoryBean获取Bean源码实现

    原型Bean加载过程 之前的文章,分析了非懒加载的单例Bean整个加载过程,除了非懒加载的单例Bean之外,Spring中还有一种Bean就是原型(Prototype)的Bean,看一下定义方式: & ...

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

    前言:spring主要就是对bean进行管理,因此IOC容器的初始化过程非常重要,搞清楚其原理不管在实际生产或面试过程中都十分的有用.在[spring源码分析]准备工作中已经搭建好spring的环境, ...

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

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

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

    前言:在[spring源码分析]IOC容器初始化(二)中已经得到了XML配置文件的Document实例,下面分析bean的注册过程. XmlBeanDefinitionReader#registerB ...

  9. 【Spring源码分析】Bean加载流程概览(转)

    转载自:https://www.cnblogs.com/xrq730/p/6285358.html 代码入口 之前写文章都会啰啰嗦嗦一大堆再开始,进入[Spring源码分析]这个板块就直接切入正题了. ...

随机推荐

  1. jmeter使用手册

    1.在bin文件中找到jmeter.bat文件启动 2.创建测试计划-填写计划名称 3.添加线程组(右键点击) 4.设置线程-红框内均可设置,线程数-并发次数 5.在线程组下添加http请求 6.在h ...

  2. CSS Sprites ——雪碧图的使用方法

    首先解释下CSS Sprites是什么:有称CSS精灵,有称CSS雪碧的,无论叫什么,他的作用就是把网页上很多小图标放到一张图片里面,然后通过CSS里面的background-position来控制每 ...

  3. Mawawa CSS 学习之旅 Display

    CSS 类型之 Display 更新时间: 2018-2-10: 一个良好的布局结构从 display 开始! 分类:外部值.内部值.列表值.属性值.混合值.显示值.全局值: 一.外部值 作用:主要用 ...

  4. PAT乙级考前总结(一)

    数学相关的题目 1001 害死人不偿命的(3n+1)猜想 (15 分) 直接一步步计数 1005 继续(3n+1)猜想 (25 分) 卡拉兹(Callatz)猜想已经在1001中给出了描述.在这个题目 ...

  5. 2.7 while 、for 循环控制语句

    一.while语句: 在程序中,需要重复性的做某件事: 1.1.1 while: public class Test{ public static void main(String[] args){ ...

  6. mysql执行sql脚本文件

    mysql执行sql脚本文件 方法一:使用cmd命令执行(windows下,unix或Linux在的其控制台下) [MySQL的bin目录]\mysql –u用户名 –p密码 –D数据库<[sq ...

  7. C# 枚举用法

    public static class EnumExtensions { public static string GetDescription(this Enum value) { return v ...

  8. Dotnetty 的心跳

    只要你不按照实例中使用libuv,就不会有问题了. 主要区别在于 WorkerEventLoopGroup 和 MultithreadEventLoopGroup 之间.

  9. 《大型网站系统与Java中间件实现》有感

    头一次只用了一周的时间就看完一本书<大型网站系统与Java中间件实现>,这本书是关于设计方面的,提到了服务框架,消息中间件,数据访问层,以及如何解决应用之间的调用,解耦,以及应用和存储之间 ...

  10. node连接mongodb(简略版)

    1.先通过配置启动mongodb,然后新建db.js     已经对相对应的数据库操作增删改查封装完成. //这个模块里面封装了所有对数据库的常用操作 var MongoClient = requir ...