第三章
spring自帶4種類型的裝配方式:按照bean的屬性名稱自動(dòng)裝配bean(byName)、按照bean的屬性類型自動(dòng)裝配bean(byType)、按照與bean構(gòu)造器入?yún)⒕哂邢嗤愋妥詣?dòng)裝配bean(constructor)和按照構(gòu)造器和屬性類型的先后順序自動(dòng)裝配bean(autodetect)
byName方式裝配的缺點(diǎn):bean的名稱要和要裝配的bean屬性的名稱一致
byType方式裝配的缺點(diǎn):如果找到多個(gè)與待裝配的bean的類型都一樣,spring會(huì)因?yàn)椴恢涝撗b配哪一個(gè)bean而拋出異常??梢允褂?lt;bean>元素的primary屬性來設(shè)置首選bean,可以使用<bean>元素的autowire-candidate屬性來設(shè)置在自動(dòng)裝配時(shí)排除哪些bean
constructor方式裝配的缺點(diǎn):和byType方式一樣,找到多個(gè)合適得bean,會(huì)因?yàn)椴恢赖降滓b配哪一個(gè)bean而拋異常
spring默認(rèn)設(shè)置自動(dòng)裝配為none(即default-autowire屬性值為none),即所有bean都不進(jìn)行自動(dòng)裝配
設(shè)置default-autowire為某個(gè)值時(shí),并不是設(shè)置了應(yīng)用上下文中的所有bean都是對(duì)應(yīng)的裝配方式,而是僅對(duì)設(shè)置的當(dāng)前配置文件中的所有bean的裝配方式為指定的裝配方式
自動(dòng)裝配和手動(dòng)顯式裝配可以混用
spring默認(rèn)關(guān)閉注解式裝配。使用<context:annotation-config>來啟用
spring支持常用的@Autowired、@Inject和@Resource注解來實(shí)現(xiàn)自動(dòng)裝配
@Autowired可以寫在構(gòu)造方法、普通方法和私有變量上,但是必須保證只能找到一個(gè)與之匹配的bean,否則spring會(huì)因?yàn)椴恢姥b配哪一個(gè)bean而拋異常。同時(shí)它還有個(gè)額外的屬性-required,設(shè)置為false則當(dāng)找不到要裝配得bean時(shí)不至于拋異常,而是設(shè)置為null
@Autowired可以配合@Qualifier使用byName的裝配方式來縮小裝配的范圍
@Inject是在Java中標(biāo)準(zhǔn)的注解,可以和spring中的@Autowired注解等價(jià)互換。只不過@Inject要求要裝配的bean一定要存在,否則會(huì)拋異常
spring中的@Autowired可以配合@Qualifier限定裝配范圍以更精確更適合的進(jìn)行裝配,那么Java中的@Inject也可以配合@Named限定。@Named使用bean的id進(jìn)行限定
第二張中提到的spEL,在使用@Value注解來注入簡(jiǎn)單值時(shí),也可用spEL的特性。如:動(dòng)態(tài)計(jì)算
使用<context:component-scan>元素代替<context:annotation-config>,同時(shí)具有自動(dòng)掃描檢測(cè)bean和開啟注解式的裝配方式
使用@Configuration注解就等同于在XML配置文件中的配置的<beans>根元素,表示是一個(gè)bean的配置集合
使用注解創(chuàng)建一個(gè)bean時(shí),當(dāng)前bean又依賴另外一個(gè)bean才能成功創(chuàng)建,則調(diào)用另一個(gè)bean的方法即可。但實(shí)際上在默認(rèn)情況下,spring仍會(huì)返回此bean的同一個(gè)實(shí)例
總結(jié):
spring支持多種自動(dòng)裝配得注解,比如Java中的@Inject
@Autowired、@Inject和@Resource注解都能實(shí)現(xiàn)自動(dòng)裝配,但使用場(chǎng)景不同,不能用錯(cuò)場(chǎng)景
@Value注解中也能使用spEL表達(dá)式
第四章
分布于應(yīng)用中的多處功能,稱為橫切關(guān)注點(diǎn)
切點(diǎn)的定義會(huì)匹配通知要織入的n個(gè)連接點(diǎn)
通知和切點(diǎn)的結(jié)合,稱為切面。切面的工作,稱為通知
aop可以在不修改原有類的情況下,為其賦予新的行為和狀態(tài)(代理)
將切面應(yīng)用到目標(biāo)對(duì)象來創(chuàng)建新的代理對(duì)象的過程,稱為織入
織入的時(shí)機(jī)分類:
編譯期 - 典型代表:AspectJ
類加載期 - 典型代表:AspectJ 5的LTW
運(yùn)行期 - 典型代表:spring aop
spring是在運(yùn)行期將切面織入spring管理的bean中的。代理類封裝了目標(biāo)類,并攔截被通知方法的調(diào)用,再講調(diào)用轉(zhuǎn)發(fā)給真正的bean
只有在使用applicationcontext,從bean工廠加載bean時(shí)才會(huì)創(chuàng)建bean的代理對(duì)象,否則一般只會(huì)在需要用到相關(guān)bean時(shí),才會(huì)去創(chuàng)建代理對(duì)象
spring aop是一個(gè)功能弱化的aop的實(shí)現(xiàn),只支持方法級(jí)別的攔截,且也不支持構(gòu)造器通知(Java的構(gòu)造方法很特殊,spring的aop功能較弱無法支持bean創(chuàng)建前后的通知)。如果不滿足則需要配合AspectJ來實(shí)現(xiàn)高級(jí)aop
使用<aop:aspect>元素定義切面,使用<aop:config>元素標(biāo)示配置是頂層的aop配置
使用環(huán)繞通知時(shí),建議一定要調(diào)用ProceedingJointPoint對(duì)象的proceed()方法,如果不調(diào)用,則將不會(huì)調(diào)用目標(biāo)方法
spring自帶了自動(dòng)代理創(chuàng)建類,只要在XMLw配置文件中應(yīng)用<aop:aspectj-autoproxy />元素即可開啟,他會(huì)自動(dòng)代理bean,且這些bean要配合使用@Aspect注解
雖然類被配置成了切面,但同時(shí)也可以正常地裝配成普通的bean來使用
總結(jié):
aop有很多廠商的實(shí)現(xiàn),spring自己也實(shí)現(xiàn)了一套,是基于方法的
spring aop在一般情況下,只有當(dāng)用到bean時(shí)才回去創(chuàng)建它的代理
spring aop是在運(yùn)行時(shí)aop容器為代理的bean自動(dòng)創(chuàng)建代理對(duì)象,是動(dòng)態(tài)代理,它不需要特殊的編譯器來織入切面。而aspectj是編譯期,故需要編譯器支持來織入