原委
很簡單的一個錯誤,今天在項目中注入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ㄒ)/~~。