@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 ...
随机推荐
- java8种基本数据类型
- 以stm32f407为例,学习cortex-m4通用寄存器的用法
测试代码如下: int add(int a, int b, int c, int d, int e, int f) { return a+b+c+d+e+f; } int main(void) { i ...
- python 读取域名信息
#!/usr/bin/env python # _*_coding:utf-8_*_ import OpenSSL from OpenSSL import crypto from dateutil i ...
- Cacti 抓取数据方式 安装spine
安装好cacti后首先要设置获取数据的方式 Cacti 获取数据的方式有两种,1.监控端的脚本(可以是php, shell, perl 或其他脚本)2.或者 snmp 协议获取. Cacti 会在固定 ...
- Rip 动态路由协议
路由信息协议(RIP) 是内部网关协议IGP中最先得到广泛使用的协议. Routing Information Protocol) RIP是一种分布式的基于距离矢量的路由 ...
- 数组和CLR-非常特殊的关系
目录 数组和CLR-非常特殊的关系 公共语言运行时(CLR)的基础 内存和类型安全 实现细节 特殊帮助器类 移除边界检查 分配数组 运行时以不同的方式对待数组 进一步阅读 数组源码引用 参考文档 数组 ...
- 【HDU - 2859 】Phalanx (dp 最大对称子图)
Phalanx 先搬翻译 Descriptions: 给你一个矩阵,只由小写或大写字母构成.求出它的最大对称子矩阵的边长. 其中对称矩阵是一个k*k的矩阵,它的元素关于从左下角到右上角的对角线对称.例 ...
- redis 5.0.7 源码阅读——跳跃表skiplist
redis中并没有专门给跳跃表两个文件.在5.0.7的版本中,结构体的声明与定义.接口的声明在server.h中,接口的定义在t_zset.c中,所有开头为zsl的函数. 一.数据结构 单个节点: t ...
- 痞子衡嵌入式:ARM Cortex-M内核那些事(6)- 系统堆栈机制
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是ARM Cortex-M堆栈机制. 今天给大家分享的这篇依旧是2016年之前痞子衡写的技术文档,花了点时间重新编排了一下格式.前面痞子衡 ...
- C#实现的一些常见时间格式
string aa = DateTime.Now.ToShortDateString();//"2019/9/23" string bb = DateTime.Now.ToShor ...