专栏名称: Java专栏
一个Java、Python、数据库、中间件、业内资讯、面试、学习资源等干货的知识分享社区。
目录
相关文章推荐
51好读  ›  专栏  ›  Java专栏

谈谈 Spring 中的 NoSuchBeanDefinitionException

Java专栏  · 公众号  ·  · 2020-11-06 12:20

正文

双11了,服务器限时限量秒杀

1核2G,1年62元,3年200元,限时秒杀

1核2G,1年62元,3年200元,限时秒杀

1核2G,1年62元,3年200元,限时秒杀

作者 | Giraffe

来源 | http://dwz.date/b4pu

概述

org.springframework.beans.factory.NoSuchBeanDefinitionException 是很常见的异常,可以说绝大多数使用过 Spring 的人都曾遇到过它。本文旨在总结下NoSuchBeanDefinitionException(以下简称 NSBDE)的含义,哪些情况下可能抛出 NSBDE,和如何解决(文中配置均用 JavaConfig)。

什么是 NoSuchBeanDefinitionException

从字面其实就很好理解,NoSuchBeanDefinitionException 就是没有找到指定 Bean 的 Definition。NoSuchBeanDefinitionException 的 JavaDoc是这样定义的:

Exception thrown when a BeanFactory is asked for a bean instance for which it cannot find a definition. This may point to a non-existing bean, a non-unique bean, or a manually registered singleton instance without an associated bean definition.

下面看看可能抛出 NSBDE 的一些情况。

情况1: No qualifying bean of type […] found for dependency

最常见的抛出 NSBDE 的情况就是在一个 BeanA 中注入 BeanB 时找不到 BeanB 的定义。例子如下:

@Component
public class BeanA {
    @Autowired
    private BeanB dependency;
    //...
}

当在 BeanA 中注入 BeanB 时,如果在 Spring 上下文中找不到 BeanB 的定义,就会抛出 NSBDE。异常信息如下:

org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [org.baeldung.packageB.BeanB]
  found for dependency: 
    expected at least 1 bean which qualifies as
  autowire candidate for this dependency. 
    Dependency annotations: 
  {@org.springframework.beans.factory.annotation.Autowired(required=true)}

抛异常的原因在异常信息中说的很清楚: expected at least 1 bean which qualifies as autowire candidate for this dependency 。所以要么是 BeanB 不存在在 Spring 上下文中(比如没有标注 @ Component,@Repository,@Service, @Controller等注解) ,要么就是 BeanB 所在的包没有被 Spring 扫描到。

解决办法就是先确认 BeanB 有没有被某些注解声明为 Bean:

package org.baeldung.packageB;
@Component
public class BeanB { ...}

如果 BeanB 已经被声明为一个 Bean,就再确认 BeanB 所在的包有没有被扫描。

@Configuration
@ComponentScan("org.baeldung.packageB")
public class ContextWithJavaConfig {
}

情况2: No qualifying bean of type […] is defined

还有一种可能抛出 NSBDE 的情况是在上下文中存在着两个 Bean,比如有一个接口 IBeanB,它有两个实现类 BeanB1 和 BeanB2。

@Component
public class BeanB1 implements IBeanB {
    //
}
@Component
public class BeanB2 implements IBeanB {
    //
}

现在,如果 BeanA 按照下面的方式注入,那么 Spring 将不知道要注入两个实现中的哪一个,就会抛出 NSBDE。

@Component
public class BeanA {
    @Autowired
    private IBeanB dependency;
}

异常信息如下:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
No qualifying bean of type
  [org.baeldung.packageB.IBeanB] is defined: 
    expected single matching bean but found 2: beanB1,beanB2

仔细看异常信息会发现,并不是直接抛出 NSBDE,而是它的子类 NoUniqueBeanDefinitionException ,这是 Spring 3.2.1 之后引入的新异常,目的就是为了和第一种找不到 Bean Definition 的情况作区分。

解决办法1就是利用 @Qualifier 注解,明确指定要注入的 Bean 的名字(BeanB2 默认的名字就是 beanB2)。







请到「今天看啥」查看全文