亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

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

系統 1881 0

2.3.1? XML配置的結構

一般配置文件結構如下:

?

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>標簽主要用來進行Bean定義;

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

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

?

2.3.2? Bean的配置

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

●全限定類名(FQN):用于定義Bean的實現類;

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

●Bean創建方式定義:說明是通過構造器還是工廠方法創建Bean;

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

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

?

2.3.3?? ?Bean的命名

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

?

?

一、? 不指定id,只配置必須的全限定類名,由IoC容器為其生成一個標識,客戶端必須通過接口“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. ???? //根據類型獲取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. //根據id獲取bean ??
  6. ????HelloApi?bean?=?beanFactory.getBean( "bean" ,?HelloApi. class );??
  7. ????bean.sayHello();??
  8. }??

?

?

三、指定name,這樣name就是“標識符”,必須在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. ???? //根據name獲取bean ??
  6. HelloApi?bean?=?beanFactory.getBean( "bean" ,?HelloApi. class );??
  7. bean.sayHello();??
  8. }??

?

?

四、指定id和name,id就是標識符,而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. ???? //根據id獲取bean ??
  6. ????HelloApi?bean1?=?beanFactory.getBean( "bean1" ,?HelloApi. class );??
  7. ????bean1.sayHello();??
  8. ???? //根據別名獲取bean ??
  9. ????HelloApi?bean2?=?beanFactory.getBean( "alias1" ,?HelloApi. class );??
  10. ????bean2.sayHello();??
  11. ???? //根據id獲取bean ??
  12. ????HelloApi?bean3?=?beanFactory.getBean( "bean3" ,?HelloApi. class );??
  13. ????bean3.sayHello();??
  14. ????String[]?bean3Alias?=?beanFactory.getAliases( "bean3" );??
  15. ???? //因此別名不能和id一樣,如果一樣則由IoC容器負責消除沖突 ??
  16. ????Assert.assertEquals( 0 ,?bean3Alias.length);??
  17. }??

?

?

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

?

java代碼:
  1. <bean?name=”?bean1;alias11,alias12;alias13?alias14”??
  2. ?????? class =”?cn.javass.spring.chapter2.helloworld.HelloImpl”/>?????
  3. <!--?當指定id時,name指定的標識符全部為別名?-->??
  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根據id獲取bean ??
  6. ????HelloApi?bean1?=?beanFactory.getBean( "bean1" ,?HelloApi. class );??
  7. ????bean1.sayHello();??
  8. ???? //2根據別名獲取bean ??
  9. ????HelloApi?alias11?=?beanFactory.getBean( "alias11" ,?HelloApi. class );??
  10. ????alias11.sayHello();??
  11. ???? //3驗證確實是四個別名??????? ??
  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. ???? //根據id獲取bean ??
  19. ????HelloApi?bean2?=?beanFactory.getBean( "bean2" ,?HelloApi. class );??
  20. ????bean2.sayHello();??
  21. ???? //2根據別名獲取bean ??
  22. ????HelloApi?alias21?=?beanFactory.getBean( "alias21" ,?HelloApi. class );??
  23. ????alias21.sayHello();??
  24. ???? //驗證確實是兩個別名 ??
  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>標簽指定別名,別名也必須在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. ???? //根據id獲取bean ??
  6. ????HelloApi?bean?=?beanFactory.getBean( "bean" ,?HelloApi. class );??
  7. ???bean.sayHello();??
  8. ???? //根據別名獲取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如果指定它們中的一個時都作為“標識符”,那為什么還要有id和name同時存在呢?這是因為當使用基于XML的配置元數據時,在XML中id是一個真正的XML id屬性,因此當其他的定義來引用這個id時就體現出id的好處了,可以利用XML解析器來驗證引用的這個id是否存在,從而更早的發現是否引用了一個不存在的bean,而使用name,則可能要在真正使用bean時才能發現引用一個不存在的bean。

?

?

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

?

2.3.4? 實例化Bean

Spring IoC容器如何實例化Bean呢?傳統應用程序可以通過new和反射方式進行實例化Bean。而Spring IoC容器則需要根據Bean定義里的配置元數據使用反射機制來創建Bean。在Spring IoC容器中根據Bean定義創建Bean主要有以下幾種方式:

一、使用構造器實例化Bean:這是最簡單的方式,Spring IoC容器即能使用默認空構造器也能使用有參數構造器兩種方式創建Bean,如以下方式指定要創建的Bean類型:

?

使用空構造器進行定義,使用此種方式,class屬性指定的類必須有空構造器

?

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

?


使用有參數構造器進行定義,使用此中方式,可以使用< constructor-arg >標簽指定構造器參數值,其中index表示位置,value表示常量值,也可以指定引用,指定引用使用ref來引用另一個Bean定義,后邊會詳細介紹:

?

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

?

知道如何配置了,讓我們做個例子的例子來實踐一下吧:

(1)準備Bean class(HelloImpl2.java),該類有一個空構造器和一個有參構造器:

?

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. <!--使用默認構造參數-->??
  2. <bean?name= "bean1" ? class = "cn.javass.spring.chapter2.HelloImpl2" />??
  3. ????<!--使用有參數構造參數-->??
  4. ???
  5. <bean?name= "bean2" ? class = "cn.javass.spring.chapter2.HelloImpl2" >??
  6. <!--?指定構造器參數?-->??
  7. ????<constructor-arg?index= "0" ?value= "Hello?Spring!" />??
  8. </bean>??

?

?

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

?

java代碼:
  1. @Test ??
  2. public ? void ?testInstantiatingBeanByConstructor()?{??
  3. ??????? //使用構造器 ??
  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. }??

?

?

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

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

?

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

?

?

(2)靜態工廠寫完了,讓我們在配置文件(resources/chapter2/instantiatingBean.xml)配置Bean定義:

?

java代碼:
  1. <!--?使用靜態工廠方法?-->??
  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. ??????? //使用靜態工廠方法 ??
  4. ???????BeanFactory?beanFactory?=??
  5. new ?ClassPathXmlApplicationContext( "chaper2/instantiatingBean.xml" );??
  6. ???????HelloApi?bean3?=?beanFactory.getBean( "bean3" ,?HelloApi. class );??
  7. ???????bean3.sayHello();??
  8. }??

?

?

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

(1)實例工廠類代碼(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)讓我們在配置文件(resources/chapter2/instantiatingBean.xml)配置Bean定義:

?

java代碼:
  1. <!— 1 、定義實例工廠Bean?-->??
  2. <bean?id= "beanInstanceFactory" ??
  3. class = "cn.javass.spring.chapter2.HelloApiInstanceFactory" />??
  4. <!— 2 、使用實例工廠Bean創建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. //使用實例工廠方法 ??
  4. ???????BeanFactory?beanFactory?=??
  5. new ?ClassPathXmlApplicationContext( "chapter2/instantiatingBean.xml" );??
  6. ???????HelloApi?bean4?=?beanFactory.getBean( "bean4" ,?HelloApi. class );??
  7. ???????bean4.sayHello();??
  8. }??

?

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

?

2.3.5? 小結

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

?

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

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


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲视频成人 | 精品香蕉99久久久久网站 | 日本伊人色综合网站 | 97在线视频免费公开观看 | 久久伦理片| 香蕉久久网 | 久久福利青草精品资源站免费 | 香蕉视频在线免费看 | 久久精品国产午夜伦班片 | 欧美精品九九99久久在观看 | 日本aaaa毛片在线看 | 免费看操片 | 99这里只有精品6 | 欧美三级午夜理伦三级小说 | 一区二区不卡不卡一卡 | 人成午夜欧美大片免费视频 | 99国产精品久久久久久久日本 | 久久久久女人精品毛片 | 91香蕉在线| 久久久久久国产精品免费免费 | 国产高清福利91成人 | 四虎影永久在线观看网址 | 欧美草逼视频 | 中文字幕一区二区三区四区五区人 | 婷婷四房综合激情五月性色 | 国产亚洲第一 | 久久国产经典视频 | 曰本毛片va看到爽不卡 | 久国产精品久久精品国产四虎 | 手机在线看片不卡中文字幕 | 青青久久久| 最新国产福利 | 黄色在线观看www | 久热精品免费 | 中文字幕国产亚洲 | 欧美高清在线视频一区二区 | 免费看在线爱爱小视频 | 欧美交换乱理伦片120秒 | 久久99热久久精品 | 在线看片福利 | 免费一级a毛片免费观看欧美大片 |