@Autowired 注入 **required a single bean, but 2 were found**

Justin發表於2019-01-19

原委

很簡單的一個錯誤,今天在專案中注入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在容器池裡面有兩個redisTemplatestringRedisTemplate(我們自己專案中配置了一個,spring boot自動配置也給我加了一個)
我定義的是field的name是redisTemplate恰好沒有,而stringRedisTemplate是有的,所以沒有問題!

解決

解決方式有很多了:

  1. field修改為stringRedisTemplate
  2. 使用@Qualifier指定注入bean
  3. 某些情況下,在衝突bean上加@Primary【不推薦】

END

這個我之前筆記記的都是對的,就是用它時候沒有遇到過這些錯誤,漸漸忘了,直到遇到了才深刻記住注入的流程,筆記裡面有些條目以為不重要就沒認真記住,記住個大概,然而沒到遇到問題前發現不了他的重要/(ㄒoㄒ)/~~。

相關文章