• 摘要:摘要:本文译自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. python中random模块的使用

    import random random.random() 产生0-1间的随机小数 >>> res = random.random() >>> print(res) ...

  2. ionic2+angularjs2

    感觉TypeScript真不错,强类型,有点类似c#的感觉,而且如果写错了编辑器都可以感知出来,于是就开始看ionic2.ionic2是基于angular2的,语法跟以前有了很大的变化.但自己写原生a ...

  3. Buy or Build(UVa1151)

    如果枚举每个套餐,并每次都求最小生成树,总时间复杂度会很高,因而需要先求一次原图的最小生成树,则枚举套餐之后需要考虑的边大大减少了. 具体见代码: #include<cstdio> #in ...

  4. freemarker demo

    <!--freemarker--> <dependency> <groupId>org.springframework.boot</groupId> & ...

  5. idea打开dashboard

    1.编辑workspace.xml文件,搜索 “RunDashboard” 节点 2.在component节点下增加option <option name="configuration ...

  6. 20164318 毛瀚逸 Exp3 免杀原理与实践

    1实验要求 1.1 正确使用msf编码器(0.5分),msfvenom生成如jar之类的其他文件(0.5分),veil-evasion(0.5分),加壳工具(0.5分),使用shellcode编程(1 ...

  7. Spring框架基础解析

    Spring是一个轻量级的.非侵入式的容器框架:对Bean对象的生命周期进行管理. Spring框架的核心:IOC(控制反转).DI(依赖注入).AOP(面向切面编程). (1) IOC:控制反转. ...

  8. 我发起并创立了一个 Javascript 前端库 开源项目 jWebForm

    在线演示地址: ( 在线演示 云平台 由 Kooboo 提供  https://www.kooboo.com/ ) 按钮:      http://iwebform.kgeking.kooboo.si ...

  9. 盘点海口最好吃的西餐厅top10

    Top 1:主厨的餐桌 餐厅地址:龙华区海秀路九号民航宾馆一楼大堂 主厨的餐桌Chef's Table是三位志同道合的大厨一起携手开办的西餐厅,正宗的西式料理.浓郁的浪漫气息,都是Chef's Tab ...

  10. C# System.Collections

    System.collection类: 动态数组ArrayList 代表了可被单独索引的对象的有序集合.也就是说他是一个动态的数组,你可以通过索引来进行增删改等操作,数组会自动调整数组的大小.允许在列 ...