日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

【第二章】 IoC 之 2.3 IoC的配置使用——跟我

系統(tǒng) 2187 0

2.3.1? XML配置的結(jié)構(gòu)

一般配置文件結(jié)構(gòu)如下:

?

java代碼:
  1. <beans>??
  2. ????< import ?resource=”resource1.xml”/>??
  3. ????<bean?id=”bean1” class =””></bean>??
  4. ????<bean?id=”bean2” class =””></bean>??
  5. <bean?name=”bean2” class =””></bean>??
  6. ????<alias?alias= "bean3" ?name= "bean2" />??
  7. ????< import ?resource=”resource2.xml”/>??
  8. </beans>??

?

?

1、<bean>標(biāo)簽主要用來進(jìn)行Bean定義;

2、alias用于定義Bean別名的;

3、import用于導(dǎo)入其他配置文件的Bean定義,這是為了加載多個(gè)配置文件,當(dāng)然也可以把這些配置文件構(gòu)造為一個(gè)數(shù)組(new String[] {“config1.xml”, config2.xml})傳給ApplicationContext實(shí)現(xiàn)進(jìn)行加載多個(gè)配置文件,那一個(gè)更適合由用戶決定;這兩種方式都是通過調(diào)用Bean Definition Reader 讀取Bean定義,內(nèi)部實(shí)現(xiàn)沒有任何區(qū)別。<import>標(biāo)簽可以放在<beans>下的任何位置,沒有順序關(guān)系。

?

2.3.2? Bean的配置

Spring IoC容器目的就是管理Bean,這些Bean將根據(jù)配置文件中的Bean定義進(jìn)行創(chuàng)建,而Bean定義在容器內(nèi)部由BeanDefinition對(duì)象表示,該定義主要包含以下信息:

●全限定類名(FQN):用于定義Bean的實(shí)現(xiàn)類;

●Bean行為定義:這些定義了Bean在容器中的行為;包括作用域(單例、原型創(chuàng)建)、是否惰性初始化及生命周期等;

●Bean創(chuàng)建方式定義:說明是通過構(gòu)造器還是工廠方法創(chuàng)建Bean;

●Bean之間關(guān)系定義:即對(duì)其他bean的引用,也就是依賴關(guān)系定義,這些引用bean也可以稱之為同事bean 或依賴bean,也就是依賴注入。

Bean定義只有“全限定類名”在當(dāng)使用構(gòu)造器或靜態(tài)工廠方法進(jìn)行實(shí)例化bean時(shí)是必須的,其他都是可選的定義。難道Spring只能通過配置方式來創(chuàng)建Bean嗎?回答當(dāng)然不是,某些SingletonBeanRegistry接口實(shí)現(xiàn)類實(shí)現(xiàn)也允許將那些非BeanFactory創(chuàng)建的、已有的用戶對(duì)象注冊(cè)到容器中,這些對(duì)象必須是共享的,比如使用DefaultListableBeanFactory 的registerSingleton() 方法。不過建議采用元數(shù)據(jù)定義。

?

2.3.3?? ?Bean的命名

?????? 每個(gè)Bean可以有一個(gè)或多個(gè)id(或稱之為標(biāo)識(shí)符或名字),在這里我們把 第一個(gè)id稱為“標(biāo)識(shí)符”,其余id叫做“別名” ;這些id在IoC容器中必須唯一。如何為Bean指定id呢,有以下幾種方式;

?

?

一、? 不指定id,只配置必須的全限定類名,由IoC容器為其生成一個(gè)標(biāo)識(shí),客戶端必須通過接口“T getBean(Class<T> requiredType)”獲取Bean;

?

java代碼:
  1. <bean? class =”?cn.javass.spring.chapter2.helloworld.HelloImpl”/>??????????????( 1 )??

?

測試代碼片段如下:

?

java代碼:
  1. @Test ??
  2. public ? void ?test1()?{??
  3. BeanFactory?beanFactory?=??
  4. ??? new ?ClassPathXmlApplicationContext( "chapter2/namingbean1.xml" );??
  5. ???? //根據(jù)類型獲取bean ??
  6. ????HelloApi?helloApi?=?beanFactory.getBean(HelloApi. class );??
  7. ????helloApi.sayHello();??
  8. }??

?

?

?二、指定id,必須在Ioc容器中唯一;

?

java代碼:
  1. <bean?id=”?bean”? class =”?cn.javass.spring.chapter2.helloworld.HelloImpl”/>????( 2 )??

?

測試代碼片段如下:

?

java代碼:
  1. @Test ??
  2. public ? void ?test2()?{??
  3. BeanFactory?beanFactory?=??
  4. new ?ClassPathXmlApplicationContext( "chapter2/namingbean2.xml" );??
  5. //根據(jù)id獲取bean ??
  6. ????HelloApi?bean?=?beanFactory.getBean( "bean" ,?HelloApi. class );??
  7. ????bean.sayHello();??
  8. }??

?

?

三、指定name,這樣name就是“標(biāo)識(shí)符”,必須在Ioc容器中唯一;

?

java代碼:
  1. <bean?name=”?bean”? class =”?cn.javass.spring.chapter2.helloworld.HelloImpl”/>?( 3 )??

?

測試代碼片段如下:

?

java代碼:
  1. @Test ??
  2. public ? void ?test3()?{??
  3. ????BeanFactory?beanFactory?=??
  4. new ?ClassPathXmlApplicationContext( "chapter2/namingbean3.xml" );??
  5. ???? //根據(jù)name獲取bean ??
  6. HelloApi?bean?=?beanFactory.getBean( "bean" ,?HelloApi. class );??
  7. bean.sayHello();??
  8. }??

?

?

四、指定id和name,id就是標(biāo)識(shí)符,而name就是別名,必須在Ioc容器中唯一;

?

java代碼:
  1. <bean?id=”bean1”name=”alias1”??
  2. class =”?cn.javass.spring.chapter2.helloworld.HelloImpl”/>??
  3. <!--?如果id和name一樣,IoC容器能檢測到,并消除沖突?-->??
  4. <bean?id= "bean3" ?name= "bean3" ? class = "cn.javass.spring.chapter2.helloworld.HelloImpl" />??????????????( 4 )??

??

測試代碼片段如下:

?

java代碼:
  1. @Test ??
  2. public ? void ?test4()?{??
  3. BeanFactory?beanFactory?=??
  4. new ?ClassPathXmlApplicationContext( "chapter2/namingbean4.xml" );??
  5. ???? //根據(jù)id獲取bean ??
  6. ????HelloApi?bean1?=?beanFactory.getBean( "bean1" ,?HelloApi. class );??
  7. ????bean1.sayHello();??
  8. ???? //根據(jù)別名獲取bean ??
  9. ????HelloApi?bean2?=?beanFactory.getBean( "alias1" ,?HelloApi. class );??
  10. ????bean2.sayHello();??
  11. ???? //根據(jù)id獲取bean ??
  12. ????HelloApi?bean3?=?beanFactory.getBean( "bean3" ,?HelloApi. class );??
  13. ????bean3.sayHello();??
  14. ????String[]?bean3Alias?=?beanFactory.getAliases( "bean3" );??
  15. ???? //因此別名不能和id一樣,如果一樣則由IoC容器負(fù)責(zé)消除沖突 ??
  16. ????Assert.assertEquals( 0 ,?bean3Alias.length);??
  17. }??

?

?

五、指定多個(gè)name,多個(gè)name用“,”、“;”、“ ”分割,第一個(gè)被用作標(biāo)識(shí)符,其他的(alias1、alias2、alias3)是別名,所有標(biāo)識(shí)符也必須在Ioc容器中唯一;

?

java代碼:
  1. <bean?name=”?bean1;alias11,alias12;alias13?alias14”??
  2. ?????? class =”?cn.javass.spring.chapter2.helloworld.HelloImpl”/>?????
  3. <!--?當(dāng)指定id時(shí),name指定的標(biāo)識(shí)符全部為別名?-->??
  4. <bean?id= "bean2" ?name= "alias21;alias22" ??
  5. class = "cn.javass.spring.chapter2.helloworld.HelloImpl" />??????????????( 5 )??

?

? 測試代碼片段如下:

?

java代碼:
  1. @Test ??
  2. public ? void ?test5()?{??
  3. BeanFactory?beanFactory?=??
  4. new ?ClassPathXmlApplicationContext( "chapter2/namingbean5.xml" );??
  5. ???? //1根據(jù)id獲取bean ??
  6. ????HelloApi?bean1?=?beanFactory.getBean( "bean1" ,?HelloApi. class );??
  7. ????bean1.sayHello();??
  8. ???? //2根據(jù)別名獲取bean ??
  9. ????HelloApi?alias11?=?beanFactory.getBean( "alias11" ,?HelloApi. class );??
  10. ????alias11.sayHello();??
  11. ???? //3驗(yàn)證確實(shí)是四個(gè)別名??????? ??
  12. ????String[]?bean1Alias?=?beanFactory.getAliases( "bean1" );??
  13. ????System.out.println( "=======namingbean5.xml?bean1?別名========" );??
  14. ???? for (String?alias?:?bean1Alias)?{??
  15. ????????System.out.println(alias);??
  16. ????}??
  17. ????Assert.assertEquals( 4 ,?bean1Alias.length);??
  18. ???? //根據(jù)id獲取bean ??
  19. ????HelloApi?bean2?=?beanFactory.getBean( "bean2" ,?HelloApi. class );??
  20. ????bean2.sayHello();??
  21. ???? //2根據(jù)別名獲取bean ??
  22. ????HelloApi?alias21?=?beanFactory.getBean( "alias21" ,?HelloApi. class );??
  23. ????alias21.sayHello();??
  24. ???? //驗(yàn)證確實(shí)是兩個(gè)別名 ??
  25. ????String[]?bean2Alias?=?beanFactory.getAliases( "bean2" );??
  26. ????System.out.println( "=======namingbean5.xml?bean2?別名========" );??
  27. ???? for (String?alias?:?bean2Alias)?{??
  28. ????????System.out.println(alias);??
  29. ????}?????
  30. ????Assert.assertEquals( 2 ,?bean2Alias.length);?????
  31. }??

?

?

六、使用<alias>標(biāo)簽指定別名,別名也必須在IoC容器中唯一

?

java代碼:
  1. <bean?name= "bean" ? class = "cn.javass.spring.chapter2.helloworld.HelloImpl" />??
  2. <alias?alias= "alias1" ?name= "bean" />??
  3. <alias?alias= "alias2" ?name= "bean" />??????????????????????????????????( 6 )??

?

?測試代碼片段如下:

?

java代碼:
  1. @Test ??
  2. public ? void ?test6()?{??
  3. BeanFactory?beanFactory?=??
  4. new ?ClassPathXmlApplicationContext( "chapter2/namingbean6.xml" );??
  5. ???? //根據(jù)id獲取bean ??
  6. ????HelloApi?bean?=?beanFactory.getBean( "bean" ,?HelloApi. class );??
  7. ???bean.sayHello();??
  8. ???? //根據(jù)別名獲取bean ??
  9. ????HelloApi?alias1?=?beanFactory.getBean( "alias1" ,?HelloApi. class );??
  10. ????alias1.sayHello();??
  11. ????HelloApi?alias2?=?beanFactory.getBean( "alias2" ,?HelloApi. class );??
  12. ????alias2.sayHello();??
  13. ????String[]?beanAlias?=?beanFactory.getAliases( "bean" );??
  14. ????System.out.println( "=======namingbean6.xml?bean?別名========" );??
  15. ???? for (String?alias?:?beanAlias)?{??
  16. ????????System.out.println(alias);??
  17. ???}??
  18. ???System.out.println( "=======namingbean6.xml?bean?別名========" );??
  19. ????Assert.assertEquals( 2 ,?beanAlias.length);??
  20. ?}??

?

以上測試代碼在cn.javass.spring.chapter2.NamingBeanTest.java文件中。

?

從定義來看,name或id如果指定它們中的一個(gè)時(shí)都作為“標(biāo)識(shí)符”,那為什么還要有id和name同時(shí)存在呢?這是因?yàn)楫?dāng)使用基于XML的配置元數(shù)據(jù)時(shí),在XML中id是一個(gè)真正的XML id屬性,因此當(dāng)其他的定義來引用這個(gè)id時(shí)就體現(xiàn)出id的好處了,可以利用XML解析器來驗(yàn)證引用的這個(gè)id是否存在,從而更早的發(fā)現(xiàn)是否引用了一個(gè)不存在的bean,而使用name,則可能要在真正使用bean時(shí)才能發(fā)現(xiàn)引用一個(gè)不存在的bean。

?

?

?● Bean命名約定: Bean的命名遵循XML命名規(guī)范,但最好符合Java命名規(guī)范,由“字母、數(shù)字、下劃線組成“,而且應(yīng)該養(yǎng)成一個(gè)良好的命名習(xí)慣, 比如采用“駝峰式”,即第一個(gè)單詞首字母開始,從第二個(gè)單詞開始首字母大寫開始,這樣可以增加可讀性。

?

2.3.4? 實(shí)例化Bean

Spring IoC容器如何實(shí)例化Bean呢?傳統(tǒng)應(yīng)用程序可以通過new和反射方式進(jìn)行實(shí)例化Bean。而Spring IoC容器則需要根據(jù)Bean定義里的配置元數(shù)據(jù)使用反射機(jī)制來創(chuàng)建Bean。在Spring IoC容器中根據(jù)Bean定義創(chuàng)建Bean主要有以下幾種方式:

一、使用構(gòu)造器實(shí)例化Bean:這是最簡單的方式,Spring IoC容器即能使用默認(rèn)空構(gòu)造器也能使用有參數(shù)構(gòu)造器兩種方式創(chuàng)建Bean,如以下方式指定要?jiǎng)?chuàng)建的Bean類型:

?

使用空構(gòu)造器進(jìn)行定義,使用此種方式,class屬性指定的類必須有空構(gòu)造器

?

java代碼:
  1. <bean?name= "bean1" ? class = "cn.javass.spring.chapter2.HelloImpl2" />??

?


使用有參數(shù)構(gòu)造器進(jìn)行定義,使用此中方式,可以使用< constructor-arg >標(biāo)簽指定構(gòu)造器參數(shù)值,其中index表示位置,value表示常量值,也可以指定引用,指定引用使用ref來引用另一個(gè)Bean定義,后邊會(huì)詳細(xì)介紹:

?

java代碼:
  1. <bean?name= "bean2" ? class = "cn.javass.spring.chapter2.HelloImpl2" >??
  2. <!--?指定構(gòu)造器參數(shù)?-->??
  3. ?????<constructor-arg?index= "0" ?value= "Hello?Spring!" />??
  4. </bean>??

?

知道如何配置了,讓我們做個(gè)例子的例子來實(shí)踐一下吧:

(1)準(zhǔn)備Bean class(HelloImpl2.java),該類有一個(gè)空構(gòu)造器和一個(gè)有參構(gòu)造器:

?

java代碼:
  1. package ?cn.javass.spring.chapter2;???
  2. ?? public ? class ?HelloImpl2? implements ?HelloApi?{??
  3. ??????????? private ?String?message;??
  4. ?????? public ?HelloImpl2()?{??
  5. ?????????????????? this .message?=? "Hello?World!" ;??
  6. ???????????}??
  7. ?????????Public?HelloImpl2(String?message)?{??
  8. ?????????????????? this .message?=?message;??
  9. ???????????}??
  10. ??????????? @Override ??
  11. ??????????? public ? void ?sayHello()?{??
  12. ??????????????????System.out.println(message);??
  13. ???????????}??
  14. }??
  15. ???

?

(2)在配置文件(resources/chapter2/instantiatingBean.xml)配置Bean定義,如下所示:

?

java代碼:
  1. <!--使用默認(rèn)構(gòu)造參數(shù)-->??
  2. <bean?name= "bean1" ? class = "cn.javass.spring.chapter2.HelloImpl2" />??
  3. ????<!--使用有參數(shù)構(gòu)造參數(shù)-->??
  4. ???
  5. <bean?name= "bean2" ? class = "cn.javass.spring.chapter2.HelloImpl2" >??
  6. <!--?指定構(gòu)造器參數(shù)?-->??
  7. ????<constructor-arg?index= "0" ?value= "Hello?Spring!" />??
  8. </bean>??

?

?

(3)配置完了,讓我們寫段測試代碼(InstantiatingContainerTest)來看下是否工作吧:

?

java代碼:
  1. @Test ??
  2. public ? void ?testInstantiatingBeanByConstructor()?{??
  3. ??????? //使用構(gòu)造器 ??
  4. ?????BeanFactory?beanFactory?=??
  5. new ?ClassPathXmlApplicationContext( "chapter2/instantiatingBean.xml" );??
  6. ???????HelloApi?bean1?=?beanFactory.getBean( "bean1" ,?HelloApi. class );??
  7. ???????bean1.sayHello();??
  8. ???????HelloApi?bean2?=?beanFactory.getBean( "bean2" ,?HelloApi. class );??
  9. ???????bean2.sayHello();??
  10. }??

?

?

二、使用靜態(tài)工廠方式實(shí)例化Bean,使用這種方式除了指定必須的class屬性,還要指定factory-method屬性來指定實(shí)例化Bean的方法,而且使用靜態(tài)工廠方法也允許指定方法參數(shù),spring IoC容器將調(diào)用此屬性指定的方法來獲取Bean,配置如下所示:

?? (1)先來看看靜態(tài)工廠類代碼吧HelloApiStaticFactory:

?

java代碼:
  1. public ? class ?HelloApiStaticFactory?{??
  2. ???? //工廠方法 ??
  3. ??????? public ? static ?HelloApi?newInstance(String?message)?{??
  4. ?????????????? //返回需要的Bean實(shí)例 ??
  5. ??????????? return ? new ?HelloImpl2(message);??
  6. }??
  7. }??

?

?

(2)靜態(tài)工廠寫完了,讓我們?cè)谂渲梦募?resources/chapter2/instantiatingBean.xml)配置Bean定義:

?

java代碼:
  1. <!--?使用靜態(tài)工廠方法?-->??
  2. <bean?id= "bean3" ? class = "cn.javass.spring.chapter2.HelloApiStaticFactory" ?factory-method= "newInstance" >??
  3. ?????<constructor-arg?index= "0" ?value= "Hello?Spring!" />??
  4. </bean>??

?

?

(3)配置完了,寫段測試代碼來測試一下吧,InstantiatingBeanTest:

?

java代碼:
  1. @Test ??
  2. public ? void ?testInstantiatingBeanByStaticFactory()?{??
  3. ??????? //使用靜態(tài)工廠方法 ??
  4. ???????BeanFactory?beanFactory?=??
  5. new ?ClassPathXmlApplicationContext( "chaper2/instantiatingBean.xml" );??
  6. ???????HelloApi?bean3?=?beanFactory.getBean( "bean3" ,?HelloApi. class );??
  7. ???????bean3.sayHello();??
  8. }??

?

?

三、使用實(shí)例工廠方法實(shí)例化Bean,使用這種方式不能指定class屬性,此時(shí)必須使用factory-bean屬性來指定工廠Bean,factory-method屬性指定實(shí)例化Bean的方法,而且使用實(shí)例工廠方法允許指定方法參數(shù),方式和使用構(gòu)造器方式一樣,配置如下:

(1)實(shí)例工廠類代碼(HelloApiInstanceFactory.java)如下:

?

java代碼:
  1. ??????
  2. package ?cn.javass.spring.chapter2;??
  3. public ? class ?HelloApiInstanceFactory?{??
  4. public ?HelloApi?newInstance(String?message)?{??
  5. ?????????? return ? new ?HelloImpl2(message);??
  6. ???}??
  7. }??
  8. ???
  9. ???

?

(2)讓我們?cè)谂渲梦募?resources/chapter2/instantiatingBean.xml)配置Bean定義:

?

java代碼:
  1. <!— 1 、定義實(shí)例工廠Bean?-->??
  2. <bean?id= "beanInstanceFactory" ??
  3. class = "cn.javass.spring.chapter2.HelloApiInstanceFactory" />??
  4. <!— 2 、使用實(shí)例工廠Bean創(chuàng)建Bean?-->??
  5. <bean?id= "bean4" ??
  6. factory-bean= "beanInstanceFactory" ??
  7. ?????factory-method= "newInstance" >??
  8. ?<constructor-arg?index= "0" ?value= "Hello?Spring!" ></constructor-arg>??
  9. </bean>??

?

(3)測試代碼InstantiatingBeanTest:

?

java代碼:
  1. @Test ??
  2. public ? void ?testInstantiatingBeanByInstanceFactory()?{??
  3. //使用實(shí)例工廠方法 ??
  4. ???????BeanFactory?beanFactory?=??
  5. new ?ClassPathXmlApplicationContext( "chapter2/instantiatingBean.xml" );??
  6. ???????HelloApi?bean4?=?beanFactory.getBean( "bean4" ,?HelloApi. class );??
  7. ???????bean4.sayHello();??
  8. }??

?

?????? 通過以上例子我們已經(jīng)基本掌握了如何實(shí)例化Bean了,大家是否注意到?這三種方式只是配置不一樣,從獲取方式看完全一樣,沒有任何不同。這也是Spring IoC的魅力,Spring IoC幫你創(chuàng)建Bean,我們只管使用就可以了,是不是很簡單。

?

2.3.5? 小結(jié)

?????? 到此我們已經(jīng)講完了Spring IoC基礎(chǔ)部分,包括IoC容器概念,如何實(shí)例化容器,Bean配置、命名及實(shí)例化,Bean獲取等等。不知大家是否注意到到目前為止,我們只能通過簡單的實(shí)例化Bean,沒有涉及Bean之間關(guān)系。接下來一章讓我們進(jìn)入配置Bean之間關(guān)系章節(jié),也就是依賴注入。?

?

同步發(fā)布到私塾在線【 http://***/forum/blogPost/list/2433.html

【第二章】 IoC 之 2.3 IoC的配置使用——跟我學(xué)Spring3


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 肇州县| 镇沅| 乐山市| 玉环县| 惠东县| 射洪县| 宜黄县| 凭祥市| 辽源市| 游戏| 永川市| 郁南县| 二连浩特市| 曲沃县| 老河口市| 芮城县| 万载县| 安顺市| 抚顺市| 崇明县| 陇南市| 常熟市| 霍林郭勒市| 徐闻县| 武冈市| 罗平县| 牟定县| 陆良县| 汝州市| 弋阳县| 芜湖市| 晋中市| 威远县| 安远县| 兴隆县| 确山县| 土默特右旗| 荣昌县| 右玉县| 漠河县| 利津县|