双11了,服务器限时限量秒杀
作者 |
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)。