问题描述:
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.test.service.PersonService' available.
bean注入失败,可以分为两种情况:
- 第一种,即要注入的bean没有定义。
- 第二种,注入的写法有问题,导致bean注入失败。
一、要注入的bean没有定义
1.如果是采用XML方式,在配置bean标签的时候,一定要仔细检查id和class是否写对。
示例:
<!-- 认真检查class路径是否正确对应了需要注入的bean的路径 -->
<bean id="person" class="com.test.service.PersonService">
2.如果是采用注解方式注入Bean,要检查需要注入的bean上 是否有 根据需要 标明如下:
@Controller、@Service、@Repository、@Component 注解中的一个。
再检查包扫描的路径是否包含有这个类。
二、注入写法有问题
需要提前了解:
在我们使用注解注入时,经常使用的两个注解分别为@Autowired、@Resource。
两者有一定的区别。
- @Autowired由Spring提供,@Resource由J2EE提供。这里从包名能够明显区分。
- @Autowired 默认先按照type查找,后按照name查找,然后进行注入。@Resource与其相反。
1.了解了上面的区别后,对于相同的bean类型(同一接口的不同实现,同一父类的不同子类),注入的bean的名称要保持不同,否则注解则无法区分,导致注入失败。
比如:一个Animal接口,有两个不同的实现类分别为Cat、Dog。你采用如下方式注入。
则此时,你@Autowired Animal animal,则会失败。如果只有一个Cat则会成功。因为按照Animal类型,只能找到一个要注入的bean就是Cat。
//这样会报错,因为对应animal有两个bean,分别为Cat和Dog 注解无法进行区分
@Autowired
Animal animal;
推荐方式:如下。注意:采用第三种方式需要为注入的bean指定名称,@Qualifier("xxx")内的name需要 与 @Component("xxx")、或@Service("xxx"),否则仍然会报错。第三种方式并不推荐,因为前两种足够了。
//推荐方式一: 按名称注入 注解可与第二种交换,因为两者都会按类型或按名称查找,只是顺序不一样。
@Resource
Animal cat;
@Resource
Animal dog;
//推荐方式二:按类型注入 注解可与第二种交换,因为两者都会按类型或按名称查找,只是顺序不一样。
@Autowired
Cat cat;
@Autowired
Dog dog;
/*
方式三:使用@Qualifier注解指定要注入的bean的类名
这里@Qualifier("xxx")内的name要和你用@Component("xxx")、或@Service("xxx")指定的name对应。
这里bean的名称可以任意写 例如:catFirst,也是可以注入成功的.*/
@Autowired
@Qualifier("xxx")
Animal catFirst;
@Autowired
@Qualifier("xxx")
Animal dogSecond;
2.对于有相同bean的名称,则bean的类型要保持唯一,否则注解还是无法区分注入哪个,导致注入失败。(推荐解决方式同上)
3.bean没有被扫描到。
1)如果采用XML的配置方式你需要加上:
<context:component-scan base-package="com.test.service"/>
2)如果采用注解的方式你需要在配置类上加上:
@ComponentScan("com.xx")
3)在springboot项目中,如果你需要注入的bean都应放在 启动类 同级包或者其子包下,springboot会自动帮你扫描。
如果不是,你仍然需要加:
@ComponentScan("com.xx")
来进行扫描。