原委
很简单的一个错误,今天在项目中注入StringRedisTemplate对象的时候是这样写的:
@Autowired
private StringRedisTemplate redisTemplate;
然后就报错了:
Field redisTemplate in com.xxx.api.controller.XxxController required a single bean, but 2 were found:
- getRedisTemplate: defined by method 'getRedisTemplate' in class path resource [com/xxx/config/RedisConfig.class]
- stringRedisTemplate: defined by method 'stringRedisTemplate' in class path resource [org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration$RedisConfiguration.class]
一直以为@AutoWired是要么按照类型,要么按照申明的@Qualifier(“beanId”)进行注入的,和我定义的redisTemplate这个field name有啥关系。。。
但是,项目其他里面都是这么写的,也没有加@Qualifier也没有报错(而且我之前用也没报错),唯一的区别就是field的name不同,别的地方都是stringRedisTemplate,我就改了下,就真的好了。如果按照之前对@AutoWired的理解,显然这属于玄学操作。
原因
@Autowired 注解的注入规则:
经过一些代码的的测试,Autowired默认先按Type,如果同一个Type找到多个bean,则,又按照Name方式比对,如果还有多个,则报出异常。
按照报错提示:StringRedisTemplate这个类型的bean在容器池里面有两个redisTemplate,stringRedisTemplate(我们自己项目中配置了一个,spring boot自动配置也给我加了一个)
我定义的是field的name是redisTemplate恰好没有,而stringRedisTemplate是有的,所以没有问题!
解决
解决方式有很多了:
- field修改为stringRedisTemplate
- 使用@Qualifier指定注入bean
- 某些情况下,在冲突bean上加@Primary【不推荐】
END
这个我之前笔记记的都是对的,就是用它时候没有遇到过这些错误,渐渐忘了,直到遇到了才深刻记住注入的流程,笔记里面有些条目以为不重要就没认真记住,记住个大概,然而没到遇到问题前发现不了他的重要/(ㄒoㄒ)/~~。