控制反轉(zhuǎn)(IOC):不需要主動去創(chuàng)造,或者不需要自己去取。而是直接告訴我需要什么,然后你給我放進(jìn)來.
IoC模式,系統(tǒng)中通過引入實(shí)現(xiàn)了IoC模式的IoC容器,即可由IoC容器來管理對象的生命周期、依賴關(guān)系等,從而使得應(yīng)用程序的配置和依賴性規(guī)范與實(shí)際的應(yīng)用程序代碼分開。其中一個(gè)特點(diǎn)就是通過文本的配置文件進(jìn)行應(yīng)用程序組件間相互關(guān)系的配置,而不用重新修改并編譯具體的代碼
可以把IoC模式看做是工廠模式的升華,可以把IoC看作是一個(gè)大工廠,只不過這個(gè)大工廠里要生成的對象都是在XML文件中給出定義的,然后利用Java 的“反射”編程,根據(jù)XML中給出的類名生成相應(yīng)的對象。從實(shí)現(xiàn)來看,IoC是把以前在工廠方法里寫死的對象生成代碼,改變?yōu)橛蒟ML文件來定義,也就是把工廠和對象生成這兩者獨(dú)立分隔開來,目的就是提高靈活性和可維護(hù)性。
優(yōu)缺點(diǎn)編輯
IoC最大的好處是什么?因?yàn)榘褜ο笊煞旁诹薠ML里定義,所以當(dāng)我們需要換一個(gè)實(shí)現(xiàn)子類將會變成很簡單(一般這樣的對象都是實(shí)現(xiàn)于某種接口的),只要修改XML就可以了,這樣我們甚至可以實(shí)現(xiàn)對象的熱插拔(有點(diǎn)像USB接口和SCSI硬盤了)。
IoC最大的缺點(diǎn)是什么?(1)生成一個(gè)對象的步驟變復(fù)雜了(事實(shí)上操作上還是挺簡單的),對于不習(xí)慣這種方式的人,會覺得有些別扭和不直觀。(2)對象生成因?yàn)槭鞘褂梅瓷渚幊?,在效率上有些損耗。但相對于IoC提高的維護(hù)性和靈活性來說,這點(diǎn)損耗是微不足道的,除非某對象的生成對效率要求特別高。(3)缺少IDE重構(gòu)操作的支持,如果在Eclipse要對類改名,那么你還需要去XML文件里手工去改了,這似乎是所有XML方式的缺陷所在。
配置注意點(diǎn):
- bean必須要有無參的構(gòu)造函數(shù)
- id必須唯一
- 屬性的注入用setter方法注入(不只是spring,一般用反射也是一樣)
- 屬性有特殊字符的時(shí)候可以用 <![CDATA] [特殊字符] >
- 屬性如果有引用類型使用 ref="bean的id"
- null的專有標(biāo)記 <null/>
- 給級聯(lián)屬性賦值:<property name="car.maxSpeed" value="2222"/> 注意:這個(gè)car要先被初始化才可以給它的屬性賦值
- 也可以用構(gòu)造器構(gòu)造:xml里是用<constructor-arg>標(biāo)簽
- 那么如何區(qū)別重載的構(gòu)造方法,在標(biāo)簽里加上type屬性
- spring屬性可以是List set map集合
- 可以配置properties屬性值(properties是Hashtable的子類)
- 集合的bean可以拿出來,可以配置、單例的集合bean。需要導(dǎo)入util的命名空間:
<util:list id="cars">
<ref bean="car">
<ref bean="car2">
</util:list>
- 通過p可以命名空間為bean的屬性賦值
<bean id="id1" class="com.xxx.xxx.xxx.object" p:name="aa" p:name2="bb" p:name3="cc">
</bean>
- autowire 可以使用autowire進(jìn)行自動裝配:
byName根據(jù)bean的名字和當(dāng)前bean的setter風(fēng)格的屬性名進(jìn)行裝配,如果沒有則不裝配
byType是根據(jù)bean的類型和當(dāng)前bean的屬性的類型進(jìn)行裝配,如果同時(shí)又1個(gè)以上能匹配上的則拋異常
如果用了則必須都要用自動裝配
其實(shí)很少使用。 - parent=“bean的名字” 配置這個(gè)屬性后可以繼承這個(gè)bean的屬性,也可以覆蓋父類的屬性 ,也可加個(gè)abstract="true"屬性編程抽象bean,和抽象類的概念一樣,不能被實(shí)例化
- 也可以配置讓一個(gè)bean依賴于一個(gè)bean
depends-on="bean名字"
這個(gè)前置的bean會在這個(gè)bean之前創(chuàng)建好
- 配置好的bean默認(rèn)都是單例的,可以使用scope="作用域"。
作用域有:singleton單例的,prototype原型的(容器初始化時(shí)不會創(chuàng)建bean實(shí)例,而是在每次請求時(shí)創(chuàng)建一個(gè)新的bean實(shí)例),request,session對應(yīng)域?qū)ο?/li> - 我們可以使用<context:property-placeholder location="classpath:xxxx.properties">來導(dǎo)入外部的配置文件,然后我們使用${屬性名}來使用屬性值。這樣可以方便我們bean的管理,易于維護(hù)。
我們一般用實(shí)現(xiàn)ApplicationContet這個(gè)接口的實(shí)現(xiàn)類,不用BeanFactory(這個(gè)BeanFactory是給spring里自己用的)
ApplicactionContext的主要的實(shí)現(xiàn)類:
ClassPathXmlApplicationContext:從類路徑下加載配置文件
FileSystemXmlApplicationContext:從文件系統(tǒng)下加載配置文件
ConfigurableApplicationContext:對ApplicationContext的擴(kuò)展,主要是增加了兩個(gè)方法:refresh,close用來刷新和關(guān)閉上下文
WebApplicationContext是專門用來給web應(yīng)用用的,允許從web的根目錄來完成初始化工作