一、背景
最近在线上遇到了Redis的序列化问题,如图:
原因分析:
- json序列化问题,那么就需要想到 redis中set和get的是否保持一致
- 查看代码发现,get的时候使用的
@Autowired
private RedisTemplate<String,String> redisTemplate;
而获取的时候使用的是
@Resource
private RedisTemplate<String,String> redisTemplate;
3、研究发现,项目中同时存在两个RedisTemplate类型,两个类型的序列化方式不一致导致的。
- redisTemplate (别名A,后续用)的类型是 RedisTemplate<String,Object>,序列化方式为:jackson2
- stringTemplate(别名B,后续用)的类型是 RedisTemplate<String,String>,序列化方式为:String
那为什么呢?我们先看看@Autowired 和 @Resource 的区别
二、@Autowired 和 @Resource 的区别
2.1、@Resource
@Resource注入的方式以及顺序规则是:
- 通过名称寻找对应的实例、找到即返回
- 名称没有找到,则通过类型去匹配
2.2、@Autowired
@Autowired注入的方式以及顺序规则
- 通过类型去匹配(不会存在多个类型一样的,编译通不过)
三、总结
好了,废话不说了,网上都有很多这种区别的概念,就不过多的做阐述,接下来总结一下名称匹配和类型匹配
| 场景 | 匹配结果 | 分析 |
|---|---|---|
| @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 通过名称匹配的,所以在编译的时候,如果名字写不对会帮助我们报错的,写对名字就按照哪个类型来注入