異常信息 NoSuchBeanDefinitionException: No matching bean of type [...]或是NoSuchBeanDefinitionException: No unique bean of type [...] 這二者具體區別暫不深究,但究其緣由都是由於找不到某類型的bean,後面再講。java
異常信息 expected single matching bean but found 2,很好理解,以前是找不到,如今是找到不止一個,spring不知道該怎麼辦了。spring
...待補充post
這是未經考證的說法,我認爲區分爲這二者以後比較容易理解注入問題。嚴格來說注入和注出關系被以各類方式描述在了beanDefinition裏面,相似於消費者和生產者。他們的行爲每每發生在spring容器初始化時,除非指定爲了prototype。ui
排查問題時從這兩個角度來看,注入是否是不對,注出是否是不對。spa
1. 咱們必需要了解最簡單直接的方式,即prototype
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" />
就這種方式而言也另有工廠方法方式,其中還分爲靜態工廠以及實例工廠,不細講component
2. 在spring後續引入註解後,在對類施加@Service @Component @Controller @Repository這四種註解(他們在注出上做用同樣),並配置包掃描:xml
<context:component-scan base-package="com.mypackage"/>
同時配置註解的類要在包掃面的路徑以內。註解注出的bean默認的id和name是類名第一個字母改成小寫blog
注入指的是通知spring你的bean對哪些bean擁有實例或稱依賴,須要spring作「填充」。
繼承
2.2.1.顯式注入:setter注入(還有constructor注入,與此相似):
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource"> <ref>dataSource</ref> </property> </bean>
setter注入須要有對應的setter方法,請注意駝峯命名,不然拋出找不到setter的異常。constructor注入須要對應的構造方法。
2.2.2.自動裝配
default-autowire="byName/byType"
特別注意,這個東西和@autowire沒有半毛錢關係,通常出如今spring文件頭,即<beans>標籤內。這個設置會智能的掃描每一個bean有哪些setter方法,並添加相似第一條的property。也就是說有此配置後就不須要上面的<property></property>標籤了。不一樣之處在於顯式配置可自由指定所需的bean,default-autowire只有根據名稱、類型來匹配。
2.2.3.註解注入
首先要啓動註解注入,主要由AutowiredAnnotationBeanPostProcessor、 CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor以及requiredAnnotationBeanPostProcessor這四個類來負責檢測註解並實現注入的,因此spring容器須要獲得這幾個類的bean,這裏有兩種方式:
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
使用到哪一個註解就註冊對應的PostProcessor,假如使用autowired,就用這個就能夠了。其餘的具體對應關係請自行研究。
<context:annotation-config />
這個配置將隱式地向 Spring 容器註冊AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor以及equiredAnnotationBeanPostProcessor這 4 個 BeanPostProcessor。而上述的 component-scan該配置項其實也包含了自動注入上述processor的功能,所以當使用 <context:component-scan/> 後,就能夠將 <context:annotation-config/> 移除了。這是由於前者默認包含着這樣一個屬性:annotation-config="true",假如咱們將其顯式指定爲false,那麼就要另外添加<context:annotation-config/>配置。
啓動註解注入以後,固然要使用註解:
@autowired
@autowired 注入的註解,默認是按type注入,但能夠用@Qualifier("abc")改成byname。
@Autowired setAbc(@Qualifier("abc")Abc abc)
事實證實,寫在方法前面的autowire能夠無視方法名,如
@Autowired public void aaa(QuestionMarkDao questionMarkDao) { super.setBaseDao(questionMarkDao); }
這樣,和@postConstruct註解就相對比較接近了,不一樣在於前者能夠帶參數,參數會自動從容器中找對應的bean
@Autowired @Qualifier("abc") MyClass myClass;
@Resource
按name來注入的註解,找不到的時候嘗試按type注入。byName指的是優先byName,若是找不到與屬性名稱相同的bean時再按照type進行查找。這裏就會出現上面講的兩個異常了,第一種是沒找到相同名字、也沒有相同類型( No unique bean of type );第二種是有相同名字,可是類型不一樣(……);第三種是沒有找到相同名字,可是相同類型的有多個( expected single matching bean but found 2)
@Resource MyClass myClass @Resource(name="otherName") MyClass myClass
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource" />
須要引入xmlns以及schemaLocation
value和ref的區別:
前者是注入字符串值,後者注入容器內的bean(id爲ref值的bean)