• 摘要:摘要:本文译自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全栈之路----常用模块----subprocess模块

    我们经常需要通过Python去执行一条系统命令或脚本,系统的shell命令是独立于你的python进程之外的,每执行一条命令,就是发起一个新进程,通过python调用系统命令或脚本的模块在python ...

  2. vue修改框架样式/deep/

    /deep/ 父元素的样式名 /deep/ 要修改的样式名 使用 ... 貌似不行

  3. windows下启动mysql服务

    当你无法连接你的mysql数据库时,或者因为某些原因导致与mysql数据库的连接丢失时,可通过以下方式启动mysql服务 1.命令行下启动mysql服务 以管理员身份运行cmd,进入mysql安装目录 ...

  4. 第四次Scrum冲刺----Life in CCSU

    一.第四次Scrum任务 小组GitHub地址链接 个人GitHub地址链接:https://github.com/2505486985/FirstScrum 继续上次完成的任务,这次完成校园服务中的 ...

  5. 使用getInstance()方法的原因及作用

    使用getInstance()方法的原因及作用 先举例说明: 下面是一个例子,为什么要把这个类实例化?有什么好处? //实例化 public static DBConnect instance; pu ...

  6. 去除 chrome 上保存密码后的 input 框的屎黄色背景

    网上找的设置 background-color,background-image 没用,后来找到这个方法测试有效: input:-webkit-autofill { transition: backg ...

  7. KMeams算法应用:图片压缩与贝叶斯公式理解

    from sklearn.datasets import load_sample_image import matplotlib.pyplot as plt from sklearn.cluster ...

  8. numpy用法

    NumPy中创建特殊值 np.nan    np.inf nan表示数据空缺   inf表示无穷 参考:https://www.cnblogs.com/haoxi/p/9175781.html

  9. leetcode中的python学习

    list.extend() list1.extend(list2(or string)) 将list2(or string)的所有元素添加到list1中: list1.append(list2(or ...

  10. 部署activiti 5.15.1的Activiti Explorer

    1.从官网下载activiti包,将其中的activiti-explorer.war文件拷贝到tomcat的webapps目录下: 2.将mysql驱动包文件mysql-connector-java- ...