Spring NoSuchBeanDefinitionException原因分析
- 摘要:摘要:本文译自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.javapackage 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.javapackage 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.javapackage 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原因分析的更多相关文章
- 【spring源码分析】IOC容器初始化(七)
前言:在[spring源码分析]IOC容器初始化(六)中分析了从单例缓存中加载bean对象,由于篇幅原因其核心函数 FactoryBeanRegistrySupport#getObjectFromFa ...
- spring源码分析之spring-core总结篇
1.spring-core概览 spring-core是spring框架的基石,它为spring框架提供了基础的支持. spring-core从源码上看,分为6个package,分别是asm,cgli ...
- Spring源码分析——BeanFactory体系之抽象类、类分析(二)
上一篇分析了BeanFactory体系的2个类,SimpleAliasRegistry和DefaultSingletonBeanRegistry——Spring源码分析——BeanFactory体系之 ...
- 【Spring源码分析】Bean加载流程概览
代码入口 之前写文章都会啰啰嗦嗦一大堆再开始,进入[Spring源码分析]这个板块就直接切入正题了. 很多朋友可能想看Spring源码,但是不知道应当如何入手去看,这个可以理解:Java开发者通常从事 ...
- 【Spring源码分析】原型Bean实例化过程、byName与byType及FactoryBean获取Bean源码实现
原型Bean加载过程 之前的文章,分析了非懒加载的单例Bean整个加载过程,除了非懒加载的单例Bean之外,Spring中还有一种Bean就是原型(Prototype)的Bean,看一下定义方式: & ...
- 【spring源码分析】IOC容器初始化(一)
前言:spring主要就是对bean进行管理,因此IOC容器的初始化过程非常重要,搞清楚其原理不管在实际生产或面试过程中都十分的有用.在[spring源码分析]准备工作中已经搭建好spring的环境, ...
- 【spring源码分析】IOC容器初始化(二)
前言:在[spring源码分析]IOC容器初始化(一)文末中已经提出loadBeanDefinitions(DefaultListableBeanFactory)的重要性,本文将以此为切入点继续分析. ...
- 【spring源码分析】IOC容器初始化(三)
前言:在[spring源码分析]IOC容器初始化(二)中已经得到了XML配置文件的Document实例,下面分析bean的注册过程. XmlBeanDefinitionReader#registerB ...
- 【Spring源码分析】Bean加载流程概览(转)
转载自:https://www.cnblogs.com/xrq730/p/6285358.html 代码入口 之前写文章都会啰啰嗦嗦一大堆再开始,进入[Spring源码分析]这个板块就直接切入正题了. ...
随机推荐
- Spring Boot 框架的依赖管理
Spring Boot为完成不同需求的Spring应用构建,提供了多种不同的依赖管理模板,每种模板均为一系列已完成的依赖的管理.例如在我们的入门程序中,需要构建web项目,我们只需添加spring-b ...
- 一起学python-语法
1.print 输出 2.定义变量:就是给变量赋一个值 name ='haha' print (name) 3.注释代码:# 注释快捷键:Ctrl +/ 4.单双引号: 如果字符串里面有单引号,外面就 ...
- Sails -初级学习配置
新建一个命名为sails的文件夹1.安装 npm -g install sails || cnpm -g install sails 注意:安装必须是全局安装 cnpm install sails - ...
- DEV gridview根据单元格值改变其他单元格格式
string style = ""; private void gridView1_RowCellStyle(object sender, DevExpress.XtraGrid. ...
- mysql5.7在windwos下的安装
1. 下载mysql5.7的安装包 下载地址:https://dev.mysql.com/downloads/mysql/ 选择“Windows (x86, 64-bit), ZIP Archive” ...
- 小程序开发:canvas在画布上滑动,页面跟着滑动问题
微信小程序官方文档有说明,disable-scroll="true" 可以阻止页面下拉和滚动.这里有个坑,disable-scroll在真机上如果要生效,那么要给canvas绑定一 ...
- 渗透测试学习 三、Linux基础
Linux发行版本 内核+应用程序 打包在一起 一.优点: 完全免费 完全兼容POSIX 1.0标准 多用户,多任务 良好的界面 可靠安全稳定的性能 支持多种平台 丰富的网络功能 安全性更好(针对 ...
- 基于Selenium的web自动化框架
转自 : https://www.cnblogs.com/AlwinXu/p/5836709.html 1 什么是selenium Selenium 是一个基于浏览器的自动化工具,它提供了一种跨平台. ...
- RedHat7系列(Centos/Debian) FireWall 防火墙 设置
RedHat 7 系列之后 系统把默认的iptables 换成了 Firewall 所以我们要适应 这个新的防火墙管理 -------------------服务相关----------------- ...
- Intel:从屌丝逆袭成业界大佬
原创文章,转载请标明出处哈,Thanks♪(・ω・)ノ. 参考<Linux内核情景分析><深入理解计算机系统><深入理解linux内核><Orange'S:一 ...