Spring注解@Autowired、@Resource、@Qualifier使用及区别 解决:
- expected single matching bean but found 2
- No qualifying bean of type [java.lang.String] is defined: expected single matching bean but found 2:
这些错误都是由于Spring容器自动装配无法匹配合适的bean引起的,值得说明的是,在使用配置文件方式配置bean时,在配置文件中配置bean时,需要特别注意那个 name 属性,而不是 id 属性,文末举例。
在平时的spring项目中,经常看到@Autowired、@Resource、@Qualifier等注解,这篇文章就给大家分享一下我的使用经验。
1. @Autowired
使用@Autowired注解自动注入需要的引用,下面给出简单示例。
- 定义一个人类接口
package com.exc.demo.annotest;
public interface People {
String getSex();
}
- 分别创建“男人”和“女人”2个类来实现上边的人类接口
package com.exc.demo.annotest;
public class Man implements People {
@Override
public String getSex() {
return "男人";
}
}
package com.exc.demo.annotest;
public class Woman implements People {
@Override
public String getSex() {
return "女人";
}
}
- 创建PeopleFactory类
package com.exc.demo.annotest;
import org.springframework.beans.factory.annotation.Autowired;
public class PeopleFactory {
@Autowired
private People people;
@Override
public String toString() {
return "PeopleFactory{" +
"peopleSex=" + people.getSex() +
'}';
}
}
启动项目,发现报错,提取关键信息:
No unique bean of type [com.example.design.demo.People] is defined: expected single matching bean but found 2: [man, woman]
错误信息写的很明显,找到了两个类型符合的bean,但是在PeopleFactory中只需要一个,spring不知道自动帮你注入哪一个。
2. @Qualifier
上边这种情况需要使用 @Qualifier 来指定你想让spring帮你注入的那个bean的beanName解决问题
package com.exc.demo.annotest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class PeopleFactory {
@Autowired
@Qualifier("man")
private People people;
@Override
public String toString() {
return "PeopleFactory{" +
"peopleSex=" + people.getSex() +
'}';
}
}
这时候spring就会按照你指定的beanName来为你注入对应的bean。
3. @Resource
@Resource和@Autowired的使用非常相似,简单看一下使用方法。
但也有一些是不同之处,在文末会提到。
package com.exc.demo.annotest;
import javax.annotation.Resource;
public class PeopleFactory {
@Resource(name = "man")
private People man;
@Resource(type = Woman.class)
private People woman;
@Override
public String toString() {
return "PeopleFactory{" +
"manSex=" + man.getSex() +
"womenSex=" + woman.getSex() +
'}';
}
}
4. @Autowired和@Resource的区别
@Autowired 顾名思义是自动装配,@Resource 也是自动装配的功能,那么它们两个有什么区别呢?
- @Autowired 默认按照bean的类型来匹配,而 @Resource 则是默认按照引入的bean的名字来进行bean的匹配。
- 如果希望 @Autowired 也按照名字来查找相应的bean,只需要加上 @Qualifier(“xxx”) 注解来指定想注入的bean的具体name。
- 如果 @Resource 同时指定了bean的类型和名称,那么它会按照两个条件去查找对应的bean,如果有一个条件没匹配上,都会报错。
- @Autowired 是spring提供的注解,而 @Resource 则不是。这一点从引入的包就能看出。
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Resource;
5. 文末
值得说明的是,@Resource默认是按照name属性来匹配对应bean,而不是按照id属性来匹配。
以String类型举例
@Resource
private String englishName;
@Resource默认是按照name属性来匹配的
<bean name="englishName" class="java.lang.String">
√√√
</bean>
不是按照id属性来匹配
<bean id="englishName" class="java.lang.String">
xxx
</bean>