关于ssm项目启动报错Spring NoSuchBeanDefinitionException原因分析

概述

在本文中,我将通过实例向你展示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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

有一个类BeanB.java

package com.csdn.training.service;

@Component
public class BeanB {

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

配置文件applicationContext.xml

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

用一个测试类去启动拉起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");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

自动扫描包路径缺少了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.
  • 1

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>
  • 1

如果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 {

}
  • 1
  • 2
  • 3
  • 4
  • 5

两个实现类:ServiceImplA.java

package com.csdn.training.service;

import org.springframework.stereotype.Service;
@Service
public class ServiceImplA implements IService {

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

ServiceImplB.java

package com.csdn.training.service;

import org.springframework.stereotype.Service;
@Service
public class ServiceImplB implements IService {

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

package com.csdn.training.model;

import com.csdn.training.service.IService;
@Component
public class BeanA {    
    @Autowired
    private IService serviceImpl;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

然后,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
  • 1
  • 2
  • 3

上例中,有时你看到的异常信息是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
  • 1

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

package com.csdn.training.model;

import com.csdn.training.service.IService;
@Component
public class BeanA {
    @Autowired
    @Qualifier("serviceImplA")
    private IService serviceImpl;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

修改以后,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");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这个例子中,没有一个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
  • 1

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

ServiceImplB.java

package com.csdn.training.service;

@Service
@Transactional
public class ServiceImplB implements IService {

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

ServiceImpl.java

package com.csdn.training.service;

@Service
@Transactional
public class ServiceImplA implements IService {
    @Autowired
    @Qualifier("serviceImplB")
    private IService serviceImplB;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

结论

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

参考:https://www.cnblogs.com/dafanshu1996/p/6498784.html

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Caused by: java.lang.ClassNotFoundException: org.springframework.dao.DuplicateKeyException是一个Java异常,表示找不到org.springframework.dao.DuplicateKeyException类。这个异常通常在使用Spring框架时发生,表明在应用程序中尝试使用Springorg.springframework.dao.DuplicateKeyException类,但是找不到该类。这可能是由于缺少相关的依赖库或配置问题引起的。 要解决这个问题,可以按照以下步骤进行操作: 1. 确保你的项目中已经添加了Spring的依赖库,并且版本与你的代码兼容。可以在项目的构建文件(如pom.xml或build.gradle)中查看依赖配置,确保包含了正确的Spring相关依赖。 2. 检查你的类路径(Classpath)是否正确设置。确保所有需要的Spring库都可以被正确加载。 3. 如果你在使用Spring Boot,检查你的应用程序的启动类(通常是带有@SpringBootApplication注解的类)以确保所有必要的组件和配置都被正确加载。 4. 如果你仍然遇到问题,可以考虑更新或重新安装Spring框架,确保你使用的是最新版本,并且下载的包含了所需的类。 总结来说,Caused by: java.lang.ClassNotFoundException: org.springframework.dao.DuplicateKeyException异常表示找不到该类。解决此问题的方法包括确保依赖库正确导入,类路径正确设置,检查Spring框架的版本和重新安装等。希望这些信息对你有帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [【IDEA_SSM】Caused by: java.lang.ClassNotFoundException: org.springframework.dao.support](https://blog.csdn.net/weixin_52372189/article/details/127940538)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Android Caused by: java.lang.ClassNotFoundException解决办法](https://download.csdn.net/download/weixin_38703295/12784351)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值