@Autowired、@Resource、@Qualifier区别
@Autowired
1、属于spring的注解,如果不想和Spring耦合的太紧,就不推荐使用。
2、默认情况下,要求依赖对象必须存在,不能为null。如果允许为空,那么设置属性值required为false。
3、默认按照类型装配(byType)。到底什么是类型装配,看下边的例子:
情形1:
public interface UserService {
}
@Service
public class UserServiceImpl implements UserService {
}
@Service
public class UserServiceImpl2 implements UserService {
}
@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
@Autowired
private UserService userService;
}
分析:在上边的测试类中使用@Autowired注入时,编辑器会报错:
Could not autowire. There is more than one bean of 'UserService' type.
Beans:
userServiceImpl (UserServiceImpl.java)
userServiceImpl2 (UserServiceImpl2.java)
原因是,@Autowired是默认按照类型注入的,它就告诉代码,我就需要一个UserService类型的类就行,但是代
码却有两个UserService类型的类。这时,@Autowired还可以按照名称(userService)注入,但是也没有满足的bean,就报错了。
情形2:
public interface UserService {
}
@Service("userService")
public class UserServiceImpl implements UserService {
}
@Service
public class UserServiceImpl2 implements UserService {
}
@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
@Autowired
private UserService userService;
@org.junit.Test
public void test1(){
System.out.println(userService);
}
}
打印:
demo.springboot.Service.UserServiceImpl@47b11ec7
分析:这时@Autowired是按照名称注入的。
情形3:
public interface UserService {
}
@Service("myUserService")
public class UserServiceImpl implements UserService {
}
@Service
public class UserServiceImpl2 implements UserService {
}
@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
@Autowired
@Qualifier("myUserService")
private UserService userService;
@org.junit.Test
public void test1(){
System.out.println(userService);
}
}
打印:
demo.springboot.Service.UserServiceImpl@47b11ec7
分析:这时如果UserServiceImpl有个别名”myUserService“,那么@Autowired需要和 @Qualifier配合使用,然后根据@Qualifier中的属性值,按照名称注入。
情形4:
public interface UserService {
}
@Service
public class UserServiceImpl implements UserService {
}
@Service
@Primary
public class UserServiceImpl2 implements UserService {
}
@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
@Autowired
private UserService userService;
@org.junit.Test
public void test1(){
System.out.println(userService);
}
}
打印:
demo.springboot.Service.UserServiceImpl2@6a756082
分析:如果在UserServiceImpl或者UserServiceImpl2上加上@Primary,就有了一个优先的顺序,就会注入加了@Primary注解的类
@Resource
1、属于J2EE JSR250规范的实现。所以建议使用@Resource注解,以减少代码和Spring之间的耦合。
2、默认按照名称装配(byName),什么是安装名称装配,看下面的例子:
情形1:
public interface UserService {
}
@Service
public class UserServiceImpl implements UserService {
}
@Service
public class UserServiceImpl2 implements UserService {
}
@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
@Resource
private UserService userService;
@org.junit.Test
public void test1() {
System.out.println(userService);
}
}
分析:执行代码会报错:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'demo.springboot.Test': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'demo.springboot.Service.iface.UserService' available: expected single matching bean but found 2: userServiceImpl,userServiceImpl2
这个报错很明显,虽然编译器在起初没有报错,但是由于@Resource是默认按照名称注入的,@Resource想要一个bean的name是userService的,但是却没有,UserServiceImpl和UserServiceImpl2的beanName默认为类名小写。所以这时匹配不上名称,就会按照类型注入,但是却发现两个类型UserService的类,所以报错了(expected single matching bean but found 2)。
情形2:
public interface UserService {
}
@Service("userService")
public class UserServiceImpl implements UserService {
}
@Service
public class UserServiceImpl2 implements UserService {
}
@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
@Resource
private UserService userService;
@org.junit.Test
public void test1() {
System.out.println(userService);
}
}
打印:
demo.springboot.Service.UserServiceImpl@727320fa
分析:给UserServiceImpl的beanName写为userService,这时@Resource按照name注入了。
情形3:
public interface UserService {
}
@Service
@Primary
public class UserServiceImpl implements UserService {
}
@Service
public class UserServiceImpl2 implements UserService {
}
@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
@Resource
private UserService userService;
@org.junit.Test
public void test1() {
System.out.println(userService);
}
}
打印:
demo.springboot.Service.UserServiceImpl@44784e2f
分析:加了@Primary,@Resource就可以按照类型注入了。
@Qualifier
1、在给字段注入时,不能独立使用,必须和@Autowired配合使用。
2、给方法参数注入时,可以独立使用。
@Autowired、@Resource、@Qualifier区别的更多相关文章
- @Resource、@Autowired、@Qualifier 区别(表格显示)
@Resource.@Autowired.@Qualifier 区别(表格显示) 区别项 @Resource @Autowired @Qualifier 谁提供的 jdk提供,包是javax.anno ...
- @Autowired @Resource @Qualifier的区别
参考博文: http://www.cnblogs.com/happyyang/articles/3553687.html http://blog.csdn.net/revent/article/det ...
- Spring @Resource、@Autowired、@Qualifier区别
@Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入: @Autowired默认是按照类型装配注入的,如果想按照名称来转配注入,则需要结合@Qualif ...
- @Autowired,@Resource,@Qualifier,@Primary,@Inject的作用和区别
@Autowired注解的用法:可以用于构造器,方法,参数,字段进行属性注入,有一个required属性,默认是true,当改成false时,如果注入的属性在容器中不存在也不会报错@Resource该 ...
- @Autowired 与@Resource的区别(详细)
参考:@Autowired 与@Resource的区别(详细) spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@Pos ...
- @Autowired 与@Resource的区别详解
spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@PostConstruct以及@PreDestroy. @Resour ...
- 关于Spring注解@Component、@Repository、@Service、@Controller @Resource、@Autowired、@Qualifier 解析
1.Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository.@Service和 @Controller 其实这三个跟@Com ...
- java @Autowired与@Resource的区别
@Autowired与@Resource的区别 1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上. 2.@Autowired默认 ...
- Spring 注释 @Autowired 和@Resource 的区别
Spring 注释 @Autowired 和@Resource 的区别 一. @Autowired和@Resource都可以用来装配bean,都可以写在字段上,或者方法上. 二. @Autowired ...
- @Autowired & @Resource 区别 & 解读@Bean
一样 Autowired & @Resource 都可以用来Bean的注入,可以写在属性(字段)上.也可以写在setter方法上 不一样 1.来源不一样 @Autowired 由Spr ...
随机推荐
- 使用MS Devops 来部署CRM Solution
在D365 CE开发当中,有一个非常痛苦的问题就是开发,测试环境中的export import solution 部署问题. Devops中能很好的解决这个问题. 工作原理: 在Azure Devop ...
- Java中类的关系
在java里类的关系大致分为三种, 1.继承(a is b):继承extends,实现implement 2.包含(a has b):组合>聚合>关联.关系亲密度越来越小,一个类在另一个类 ...
- java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener,环境Spring+Maven
记录一下莫名出现的错误.Spring+Maven+STS. 严重: Error configuring application listener of class org.springframewor ...
- 动态主机配置协议-DHCP
一.DHCP 概述 当局域网中有大量的PC时.如果我们逐个为每台PC去手动配置IP.那这就是一个吃力也未必讨好的办法 累死你 而DHCP 刚好可以解决这个问题.DHCP全称(动态主机配置协议).使用的 ...
- this关键字和static关键字
this关键字 普通方法中,this总是指向调用该方法的对象. 构造方法中,this总是指向正要初始化的对象. this区分成员变量和全局变量的作用,在当前类中可以省略. this的常用方法: 让类中 ...
- 11种常用css样式之border学习
边框border通常简写为"border:1px solid red;"但其实一个完整的border边框其实是由1.border-width/*边框宽度*/,2.border-st ...
- ACP知识总结
由于ACP是一个敏捷开发的系统性知识,下面只针对我自身学习的知识总结,若需要完整的考试学习资料,可评论区或私聊我拿. 敏捷估计与规划.png ACP知识点锦集.png 敏捷项目软件总结.p ...
- windows快捷键记录
-1: 装完iis, run -> inetmgr 弹出iis管理器 0.按住Shift键右击鼠标打开命令行窗口 1.ODBC数据源管理器run->odbcad32 2.计算机管理(查看设 ...
- Oracle列转行 参数动态传入iBatis使用示例
Oracle行转列 参数动态传入iBatis使用示例 最近做了一个需求,需要获取工作流数据的各个节点的渠道数量信息,各渠道的费用信息~ 之前的需求是只需要获取渠道数据,所以做了渠道兼容,每个渠道数量的 ...
- mysql必知必会--MySQL简介
什么是MySQL MySQL已经存在很久了,它在世界范围内得到了广泛的安装和使用. 为什么有那么多的公司和开发人员使用MySQL?以下列出其原因. 成本--MySQL是开放源代码的,一般可以免费使用( ...