@Autowired 和 @Resource 的区别

80 阅读2分钟

一、背景

最近在线上遇到了Redis的序列化问题,如图:

image.png 原因分析:

  1. json序列化问题,那么就需要想到 redis中set和get的是否保持一致
  2. 查看代码发现,get的时候使用的
@Autowired
private RedisTemplate<String,String> redisTemplate;

而获取的时候使用的是

@Resource
private RedisTemplate<String,String> redisTemplate;

3、研究发现,项目中同时存在两个RedisTemplate类型,两个类型的序列化方式不一致导致的。

image.png

  • redisTemplate (别名A,后续用)的类型是 RedisTemplate<String,Object>,序列化方式为:jackson2
  • stringTemplate(别名B,后续用)的类型是 RedisTemplate<String,String>,序列化方式为:String

那为什么呢?我们先看看@Autowired 和 @Resource 的区别

二、@Autowired 和 @Resource 的区别

2.1、@Resource

@Resource注入的方式以及顺序规则是:

  1. 通过名称寻找对应的实例、找到即返回
  2. 名称没有找到,则通过类型去匹配

2.2、@Autowired

@Autowired注入的方式以及顺序规则

  1. 通过类型去匹配(不会存在多个类型一样的,编译通不过)

三、总结

好了,废话不说了,网上都有很多这种区别的概念,就不过多的做阐述,接下来总结一下名称匹配和类型匹配

场景匹配结果分析
@Autowired
private RedisTemplate<String,String> redisTemplate;A@Autowired 根据类型直接匹配到了 A
@Autowired
private RedisTemplate<String,Object> redisTemplate;B@Autowired 根据类型直接匹配到了 B
@Resource
private RedisTemplate<String,String> redisTemplate;B@Resource 根据名称直接匹配到了 B
@Resource
private RedisTemplate<String,Object> redisTemplate;B@Resource 根据名称直接匹配到了 B
@Resource
private RedisTemplate<String,String> redisTemplateXxxx;A@Resource 根据名称没有找到匹配,然后根据类型匹配到了A
@Resource
private RedisTemplate<String,Object> redisTemplateXxxxx;B@Resource 根据名称没有找到匹配,然后根据类型匹配到了B

还有一种特殊情况:

@Autowired
private RedisTemplate redisTemplate;
@Autowired
private RedisTemplate stringTemplate;

上面代码中的效果等同于用 @Resource 通过名称匹配的,所以在编译的时候,如果名字写不对会帮助我们报错的,写对名字就按照哪个类型来注入

image.png