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