案例講稿跟我學spring_第1頁
案例講稿跟我學spring_第2頁
案例講稿跟我學spring_第3頁
案例講稿跟我學spring_第4頁
案例講稿跟我學spring_第5頁
已閱讀5頁,還剩750頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

跟我學 貼及 Spring概 Spring介 Spring是什 Spring能幫我們做什 為何需要 如何學好 Spring基 Spring架構 IoC基 IoC是什 IoC能做什 IoC和 容器基本原 IoC容器的概 Bean的概 o 詳解IoC容 小 Spring概SpringSpringSpringJavaSE(Java標準版本)/JavaEE(Java企業(yè)可以幫我們創(chuàng)建對象,“模式”幫我們處理對象間的依賴關系,不也能完成這些功能嗎?可是這些又需要我們創(chuàng)建另一些工廠類、類,我們又要而外管理這些類,增加了我們的負擔,如果能有種通過配置方式來創(chuàng)建對象,管理對象之間依賴關系,我們不需要通過工廠和來創(chuàng)建及管理對象多時間來干其他事。SpringSpring事務,本身提供了一套簡單的JDBC實現(xiàn),提供與第數(shù)據(jù)框架集(Hibernate、JPA),JavaEE(JavaMail、任務調(diào)度等等),webSpringMVC、而且還能非常簡單的與第三方web框架集成。從這里我們可以認為Spring是一個超級粘合平臺,除了自己擇到底使用什么技術進行開發(fā)。而且不管是JAVASE(C/S架構)應用程序還是JAVAEE(B/S)應用程序都可以使用這個平臺進行開發(fā)。讓我們來深入看SpringSpringSpring,Spring譯。所以,Spring能幫我們根據(jù)配置文件創(chuàng)建及組裝對象之間的依賴關系行,在診斷完畢后要刪除這些代碼;還有日志記錄,比如記錄一些方法日志、數(shù)據(jù)日志等等,這些都會滲透到各個要方法中;還限控制,Spring,這些日志記錄、權限控制、性能統(tǒng)計從業(yè)務邏輯中分離出Spring“設計模式”或“包裝器設計模式”,你可以使用這些,但還是需要通過編程方式來創(chuàng)建對象,還是要耦合這些對象,而采用Spring面向切要在現(xiàn)有代碼中添加任何額外代碼,現(xiàn)有代碼專注業(yè)務邏輯。所以,Spring取連接,執(zhí)行SQL,提交或回滾事務,關閉連接”,而且還要保證在最后一定Spring,我們只需獲取連接,執(zhí)行SQL,其他的都交給Spring來管理了,簡單吧。所以,Spring能四、Spring還提供了與第數(shù)據(jù)框架(如Hibernate、JPA)無縫集成,而且自己也提供了一套JDBC模板,來方便數(shù)據(jù)庫。五、Spring還提供與第Web(如Struts、JSF)框架無縫集成,而且自己SpringMVCweb六、Spring能方便的與JavaEE(如JavaMail、任務調(diào)度)整合,與技Spring且是幫我們做了開發(fā)中比較頭疼和的事情,那可能有人會問,難道只有SpringEJBEJBSpring,而不為何需要1、應用程序:是能完成我們所需要功能的成品,比如購物、OA系統(tǒng)2、框架:是能完成一定功能的半成品,比如我們可以使用框架進行購物開4、輕量級及重量級:輕量級是相對于重量級而言的,輕量級一般就是非性5、POJO:POJO(PlainOldJavaObjectsJava框架的類或接口。7、控制反轉:InversionofControlIoC,控制反轉還有一個名字叫做依賴注入(DependencyInjection),就是由容器控制程序之間的關系,8、Bean:SpringSpringIoCSpringSpring配,負責對象創(chuàng)建和裝配,管理對象生命周期,能組合成復雜的應用程序。Spring(不需要依賴任何Spring),而且完全采用POJOs進行開發(fā),使應用程序更容易測試、更容易管理。而且JAR包非常小,Spring3.0.51M,而且不需要依賴任何應用服務器,可以部署在任何環(huán)境(JavaSEJavaEE)。AOP:AOP是AspectOrientedProgramming的縮寫,意思是面向切面編程,提供從另一個角度來考慮程序結構以完善面向對象編程(相對于OOP),即可以通過在編譯期間、裝載期間或運行期間實現(xiàn)在不修改源代碼的情況下給程序些通用功能在合適的時候織入到應用程序中;比如安全 記錄,這些都代碼并執(zhí)行它們,從而完成需要的功能并復用了這些功能。務是一項很讓人頭疼的事,而且很容易出現(xiàn)錯誤,Spring理支持,而且無需JEE環(huán)境支持,通過Spring管理事務可以把我們從事務管理JDBC抽象及ORM框架支持:SpringJDBC更加容易使用;提供DAO(數(shù)據(jù)對象)支持,非常方便集成第ORM框架,比如Hibernate等;并且完SpringSpring靈活的Web層支持:Spring本身提供一套非常強大的MVC框架,而且可以非常容易的與第MVC框架集成,比如Struts等。簡化各種技術集成JavaMail、任務調(diào)度、JMX、JMS、JNDI、EJB、動態(tài)語言、、WebService等的集成。SpringMVCSpring如何學好Spring,Spring知道了這些然后做個簡單的例子,這樣就基本知道怎么使用SpringSpring是IoC容器,所以一定要透徹理解什么是IoC容器,以及如何配置IoCSpring很重要,IoCSpringSpringSpring圖1-1Spring容器:Core、Beans、Context、ELCore模塊:封裝了框架依賴的最底層部分,包括資源、類型轉換及一些Beans塊:BeanFactory是容器,本質是“工廠設計模式”的實現(xiàn),而且無需編程實現(xiàn)實現(xiàn)編程;所有應用程序對象及對象間關系由框架管理,從而真正從程序邏輯中把對象之間的依賴關系提取出來,所有這些依賴關系都由BeanFactory來?!馛ontextCoreBeansBeans定、數(shù)據(jù)驗證、、JavaEE支持、容器生命周期、事件等;接ApplicationContext?!馝L模塊:提供強大的表達式語言支持,支和修改屬性值,方法調(diào)用支持及修改數(shù)組、容器和索引器,命名變量,支持算數(shù)和邏輯運算,支持SpringBean,它也支持列表投影、選擇和一般的列表聚合等。AOP、Aspects模塊AOPSpringAOPAOPAlliance規(guī)范的面向方面的編程(aspect-orientedprogramming)實現(xiàn),提供比如日志記錄、權限控制、性Aspects模塊:提供了對AspectJ的集成,AspectJ提供了比SpringASP更數(shù)據(jù)/集成模塊:該模塊包括了JDBC、ORM、OXM、JMS和事務管理SpringSpring性的事物管理?!馢DBCJBDCJDBCSpring●ORMHibernate、JPA、IbatissSpring●OXMObject/XMLjavaXMLXMLjava,Object/XMLJAXB、Castor、XMLBeansXStream?!馢MSJMS(JavaMessagingServiceJMS,JMSWeb/Remoting塊:Web/RemotingWeb、Web-Servlet、Web-Struts、Web-Porlet●WebwebIoC過程(RMI、Hessian、Burlap)以及WebService支持,并提供一個RestTemplate類來提供方便的Restfulservices?!馱eb-ServletSpringMVCWebSpringMVC易用的JSP,完全無縫與Spring其他技術協(xié)作。●Web-StrutsStruts,Struts1.xStruts2.xTest塊SpringJunitTestNGSpringWebHttp典型應用SpringJavaSESpring典型Web應用程序應用場景1-2webWeb層實現(xiàn)數(shù)據(jù);邏輯層實現(xiàn)業(yè)務邏輯;web層提供頁面展示;所有這些SpringSpringAOP求唯一就是DispachterServlet,它通過把請求映射為相應web層組件來應用場Spring能非常方便的提供RMI服務,服務如Hessian、等,實現(xiàn)非常簡單只需通過在Spring中配置相應的地址及需要的服務即可EJB應用場景SpringEJBIoCIoC是什Ioc—InversionofControl,即“控制反轉”,不是什么技術,而是一種設計思想。在Java開發(fā)中,IocIocIoc的關鍵是要明確“誰控制誰,控制什么,為何是反轉(有反轉就應該有正轉了),哪些方面反轉了”,那我們來深入分析一下:誰控制誰,控制什么:JavaSEnew進行IoC是有專門一個容器來創(chuàng)建這些對象,即由Ioc容器來控制對象的創(chuàng)建;誰控制誰?當然是IoC容器控制了對象;控制什么?為何是反轉,哪些方面反轉了:有反轉就有正轉,傳統(tǒng)應用程序是由我們自己在對象對象;為何是反轉?因為由容器幫我們查找及注入依賴對象,對象只是的接受依賴2-12-2有IoC/DIIoC什IoC不是一種技術,只是一種思想,一個重要的面向對象編程的法則,它能指導我們?nèi)绾味鴮е骂惻c類之間高耦合,難于測試;有了IoC容器后,把創(chuàng)建和查找依賴對象的控制權IoC對編程帶來的最大改變不是從代碼上,而是從思想上,發(fā)生了“主從換位”的變程序就變成的了,的等待IoC容器來創(chuàng)建并注入它所需要的資源了。——IoCDI—DependencyInjection,即“依賴注入”:是組件之間依賴關系由容器在運行期決軟件系統(tǒng)帶來功能,而是為了提升組件重用的頻率,并為系統(tǒng)搭建一個靈活、可擴展DI的關鍵是:“誰依賴誰,為什么需要依賴,誰注入誰,注入了什么”,那我們來深誰注入誰:很明顯是IoCIoCDI由什么關系呢?其實它們是同一個概念的不同角度描述,由于控制反轉概念比較含糊(可能只是理解為容器控制對象這一個層面,很難讓人想到對象關系),2004MartinFowler又給出了一個新的名字:“依賴注入”,相對IoC而言,“依賴注入”明確描述了“IoC容器配置依賴對象”。IoC和DIMartinFowler的一篇經(jīng)典文章《InversionofControlContainersandtheDependencyInjection /articles/injection.html。IoCIoC容器就是具有依賴注入功能的容器,IoC容器負責實例化、定位、配置應用程序中的new相關的對象,應用程序由IoCSpringBeanFactory是IoC容器的實際代表者。SpringIoC容器如何知道哪些是它管理的對象呢?這就需要配置文件,SpringIoC容器通 xmlSpring與配置文件完全解耦的,可以java文件的、基于屬性文件BeanIoCBean,BeanSpring容器bean就與應用程序中的其他對象沒有什么區(qū)別了。那IoCBeanBeanBean呢?這就需要配置元數(shù)據(jù),在SpringBeanDefinition代表,后邊會詳細介紹,配BeanBean等。概念知道的差不多了,讓我們來做o 開發(fā)工具:SpringSourceToolSuiteSTSEclipse的開發(fā)環(huán)境,用以構建Spring應用,其版開始支持Spring3.0及OSGi開發(fā)工具,但由于其Eclipse+SpringSourceTool插件進行Spring應用開發(fā);到eclipse官網(wǎng)的Eclipse,注意我們使用的是EclipseIDEforJavaEEDevelopers(eclipse-jee-helios-SR1);2-32SpringSourceToolSuite2-4:Name為:SpringSourceToolSuiteDependencies2-4Name為:SpringSourceTool2-4Spring依賴:本書使用spring-framework-spring-framework-3.0.5.RELEASE-dependencies.zipspring的jar包,所以需要什么依賴從這里找就好了;地址:二、開始SpringoWorld之旅jar包:從的spring-framework-3.0.5.RELEASE-with-docs.zip中dist依賴的jar包:從的spring-framework-3.0.5.RELEASE-dependencies.zip中jar包 選擇“window”ShowViewPackageExplorer”2-5創(chuàng)建標準Java項目,選擇“File”—>“New”—>“Other”;然后在彈出來的框中選擇“JavaProject”Java項目;2-6Java2-7Java2-8Java配置項目依賴庫文件,右擊項目選擇“Properties”;然后在彈出的框中點擊“AddJARS”在彈出的框中選擇“l(fā)ib”下的jar包;然后再點擊“AddLibrary”,然后在彈出的框中選擇“Junit”,選擇“Junit4”;2-92-102-11 結構如下圖所示,其中“src”用于存放java文件;“l(fā)ib”用于存放jar文圖2-12項 3、項目搭建好了,讓我們來開發(fā)接口,此處我們只需實現(xiàn)打印“oWorld!”,所以我java代碼publicvoid 4.publicvoid 4.oApi2.public4、接口開發(fā)好了,讓我們來通過實現(xiàn)接口來完成打印“oWorld!”功能java代碼packagepublicoImploApi o7.}publicvoid o()5、接口都開發(fā)好了,那如何使用SpringIoC容器來管理它們呢?這就需要配置文IoC容器知道要管理哪些對象。讓我們來看下配置文件 oworld.xml(放到 下java代碼<?xmlversion="1.0"encoding="UTF-""" id表示你這個組件的名字,class表示組件類10.<beano" 11.IoC容器,然后從容器中獲取需要的對象,然后調(diào)用接口完成我們需要的功能,代碼示例java代碼1.1.package 3.import5.publicoTestpublicvoid oWorld() ApplicationContextcontext=new oApi= //2、從容器中獲取Bean,注意此處完全“面向接口編程,而不是面向實現(xiàn) 配置文件實例化一個IoC容4.import2.import15.15.}7、自此一個完整的SpringoWorld已完成,是不是很簡單,讓我們深入理解下容器Bean吧。IoC容SpringIoc容器的代表就是org.springframework.beansBeanFactory接口,BeanFactory接口提供了IoC容器最基本功能;而org.springframework.contextApplicationContext接口擴展了BeanFactory,還提供了與SpringAOP集成、處理、事件及提供不同層次的context(web應用的WebApplicationContext)BeanFactory提供了IoC容器最基本功能,而ApplicationContext則增加了支持企業(yè)級功能支持。ApplicationContextBeanFactoryBeanFactory所具有的語義也ApplicationContext。(1)Filefile=newFile("fileSystemConfig.xml");Resourceresource=newFileSystemResource(file);BeanFactorybeanFactory=newResourceresource=newBeanFactorybeanFactory=newBeanFactorybeanFactory=newBeanFactorybeanFactory=newcn.javass.spring.chapter2.InstantiatingContainerTest.java。ApplicationContextBean方法簡介:ObjectgetBean(Stringname)Bean,客戶端需要自己進行類型TgetBean(StringnameClass<TrequiredType)根據(jù)名稱和指定的類型返回一Bean,客戶端無需自己進行類型轉換,如果類型轉換失敗,容器拋出異常;TgetBean(Class<T>requiredType)Bean,客戶端無需Bean存在容器將拋出異常;Map<StringTgetBeansOfType(Class<Ttype)根據(jù)指定的類型返回一個鍵值Bean對象的MapBean對象存在則返回空的Map。讓我們來看下IoC容器到底是如何工作。在此我們以xml配置方式來分析一一、準備配置文件:就像前邊oWorld配置文件一樣,在配置文件中Bean定義Bean配置元數(shù)據(jù)。Bean。2-5SpringIoc小除了測試程序的代碼外,也就是程序,所有代碼都沒有出現(xiàn)Spring任何組件,而且IoCXMLjava代碼1. <import <bean <bean5.<bean <aliasalias="bean3" <import8.3、importBean定義,這是為了加載多個配置文件,當然也可以把這些配置文件構造為一個數(shù)組(newStringconfig1.xml”config2.xml})ApplicationContext實現(xiàn)進行加載多個配置文件,那一個更適合由用戶決定;這兩種方式都是通過調(diào)用BeanDefinitionReaderBean定義,內(nèi)部實現(xiàn)沒有任何區(qū)BeanSpringIoCBeanBeanBean定義進行創(chuàng)BeanBeanDefinition對象表示,該定義主要包含以下信息:BeanBean在容器中的行為;包括作用域(單例、原型創(chuàng)建)Bean之間關系定義:即對其他bean的,也就是依賴關系定義,這些beanbeanbean,也就是依賴注入。Bean定義只有“全限定類名”bean時是必須SpringBean嗎?回答當然不SingletonBeanRegistryBeanFactory創(chuàng)建的、已有的用戶對象到容器中,這些對象必須是共享的,比如使用DefaultListableBeanFactoryregisterSingleton()方法。不過建議采用元數(shù)據(jù)定 id稱為“標識符”,其余id叫做“別名”;這些id在IoC容器中必須唯一。如何為Beanid呢,有以下幾種方式;idIoC容器為其生成一個標識,客戶端必須通過接口“TgetBean(Class<T>requiredType)”Bean;java代碼1.<bean java代碼publicvoidtest1()BeanFactorybeanFactorynew//根據(jù)類型獲取oApi=}java代碼1.<beanid=”bean”class=”cn.javass.spring.chapter2.oworld.java代碼2.publicvoid2.publicvoidtest2()3.BeanFactorybeanFactory5.5.//根據(jù)id獲取oApibean=8.4.newname,這樣name就是“標識符”Iocjava代碼1.<beanname=”bean”class=”cn.javass.spring.chapter2.oworld.java代碼BeanFactorybeanFactoryBeanFactorybeanFactory//根據(jù)name獲取oApibean=7. 8.4.new2.publicvoidtest3()id和name,idnameIocjava代碼2.class=”2.class=” 3.<!--id和name一樣,IoC o4.<beanid="bean3"name="bean3"java代碼1.3.3.BeanFactorybeanFactory//根據(jù)id獲取oApibean1=oApibean2=//根據(jù)id獲取oApibean3=//因此別名不能和id一樣,如果一樣則由IoC17.Assert.assertEquals(0, String[]bean3Alias= //根據(jù)別名獲取4.new2.publicvoidtest4()“”java代碼<bean<beanname=”bean1;alias11,alias12;alias13class=” 當指定id時,name指定的標識符全部為別名5.4.<beanid="bean2"java代碼3.BeanFactorybeanFactory3.BeanFactorybeanFactory//1根據(jù)id獲取oApibean1=oApialias11= //2根據(jù)別名獲取4.new2.publicvoidtest5() System.out.println("=======namingbean5.xmlbean1Assert.assertEquals(4,oApibean2=//2根據(jù)別名獲取oApialias21=String[]bean2Alias=for(Stringalias:bean2Alias)}31.Assert.assertEquals(2, System.out.println("=======namingbean5.xmlbean2 //根據(jù)id獲取}for(Stringalias:bean1Alias) String[]bean1Alias=六、使用<alias>指定別名,別名也必須在IoC容器中唯java代碼<bean<beanname="bean"<aliasalias="alias1"<aliasalias="alias2")java代碼2.publicvoid2.publicvoidtest6()3.BeanFactorybeanFactory4.4.new //根據(jù)id獲取oApibean=oApialias1=oApialias2=String[] ias=for(Stringalias: ias) Assert.assertEquals(2, 20. System.out.println("=======namingbean6.xmlbean別名 System.out.println("=======namingbean6.xmlbean別名 //根據(jù)別名獲取以上測試代碼在cn.javass.spring.chapter2.NamingBeanTest.java文件中從定義來看,nameid如果指定它們中的一個時都作為“標識符”idnameXMLXMLid是一個真正的XMLid屬性,因此當其他的定義來這個id時就體現(xiàn)出id的好處了,可以利用XML解析器來驗證的這個id是否存在,從而更早的發(fā)現(xiàn)是否了一個不存在的bean,而使用name,則可能要在真正使用bean時才能發(fā)現(xiàn)一個不存在的bean?!白帜?、數(shù)字、下劃線組成“,而且應該養(yǎng)成一個良好名習慣,比如采用“駝峰式”,即SpringIoCBean呢?傳統(tǒng)應用程序可以通過new和反射方式進行實例BeanSpringIoCBean定義里的配置元數(shù)據(jù)使用反射機制來創(chuàng)BeanSpringIoCBeanBean主要有以下幾種方式:Bean:這是最簡單的方式,SpringIoC容器即能使用默認空構造BeanBean類型:java代碼PAGE2.PAGE2.<beanname="bean1"使用有參數(shù)構造器進行定義,使用此中方式,可以使用<constructor-arg>指定構造器參數(shù)值,其中index表示位置,value表示常量值,也可以指定,指定使用ref來另一個Bean定義,后邊會詳細介紹:java代碼2.<!--指定構造器參數(shù)1.<beanname="bean2"class=2.<!--指定構造器參數(shù) <constructor-argindex="0"value="o4.4.java代碼packagepublicoImpl2oApiprivateStringoImpl2()this.message=o}oImpl2(Stringmessage)this.message=}publicvoido()}14.在配置文件(resources/chapter2/instantiatingBean.xml)Bean定義,如java代碼5.<beanname="bean2"<constructor-argindex="0"o8.6.<!--指定構造器參數(shù)java代碼5.newoApibean1=oApibean2=10.BeanFactorybeanFactory2.publicvoidtestInstantiatingBeanByConstructor()Beanclass屬性,還要factory-methodBean的方法,而且使用靜態(tài)工廠方法也允許java代碼1.1.publicoApiStaticFactorypublicoApinewInstance(Stringmessage)return7.6.//返回需要的Bean實javajava代碼<constructor-argindex="0"<constructor-argindex="0"o4.2.<beanid="bean3"tory"factory-java代碼5.newoApibean3=8.BeanFactorybeanFactory2.publicvoidtestInstantiatingBeanByStaticFactory()Beanclass屬性,此時必須使用factory-beanBean,factory-methodBean的方實例工廠類代碼(oApiInstanceFactory.java)如下java代碼3.publicoApiInstanceFactoryreturn7.}oApinewInstance(Stringmessage)4.2.package1.1.<!—1、定義實例工廠Bean-->3.5.<bean9.oSpring!"></constructor- <constructor-argindex="0"6.factory-4.<!—2、使用實例工廠BeanBean2.<beanjava代碼3.//3.//5.newoApibean4=8.BeanFactorybeanFactory2.publicvoidtestInstantiatingBeanByInstanceFactory()式只是配置不一樣,從獲取方式看完全一樣,沒有任何不同。這也是SpringIoC的魅力,SpringIoC幫你創(chuàng)建Bean,我們使用就可以了,是不是很簡單。小器,Bean配置、命名及實例化,Bean獲取等等。不知大家是否注意到到目前為止,我們BeanBean之間關系。接下來一章讓我們進入配置Bean之間關系章節(jié),也就是依賴注入。DIBean依賴容器:Bean要依賴于容器,這里的依賴是指容器負責創(chuàng)建BeanBeanBean并注入依賴,也就是控制權被反轉了,這也正是IoC名字的由來,Bean和容器之間的依Bean的依賴資源:Bean的依賴資源,依賴資源可以是Bean、外部文件、常量數(shù)據(jù)等,在JavaBean之間的依賴關系,Bean之間的依賴關系,可以認為是傳統(tǒng)類與類之間的Bean依賴對象,程序更靈活:Bean依賴對象,無需修改源文件:應Bean的依賴對java源文件;更好實踐面向接口編程,代碼更清晰:Bean中只需指定依賴對象的接口,接口定更好實踐優(yōu)先使用對象組合,而不是類繼承:IoC容器采用注入依賴,也就是組采用對象組合,Bean的功能可能由幾個依賴Bean的功能組合而成,其Bean本身可能只提供少許功能或根本無任何功能,全部委托給依賴Bean,對象組合具有動態(tài)性,能更方便的替換掉依賴Bean,從而改變Bean功能;了,不具有動態(tài)性,而且采用類繼承導致Bean與子Bean之間高度耦合,難以復用。Bean之間耦合:由于我們完全采用面向接口編程,在代碼中沒有直接Bean依賴實現(xiàn),全部接口,而且不會出現(xiàn)顯示的創(chuàng)建依賴對象代碼,而且這些依賴是由容器來注入,很容易替換依賴實現(xiàn)類,從而降低Bean與依賴之間耦合;從以上我們可以看出,其實依賴注入只是一種裝配對象的,設計的類結構才是基礎,如果設計的類結構不支持依賴注入,SpringIoC容器也注入不了任何東西,從而從根本構造器注入:就是容器實例化BeanBean定義中指定構方法功構造器注3-1所示:3-1數(shù)名注入是有限制的,需要使用在編譯程序時打開調(diào)試模式(即在編譯時使用“javac–g:vars”class文件中生成變量調(diào)試信息,默認是不包含變量調(diào)試信息的,從而能獲取參數(shù)名字,否則獲取不到參數(shù)名字)或在構造器上使用@ConstructorPropertiesjava代碼publicoImpl3oApipublicoImpl3oApiprivateString5.//@java.beans.ConstructorProperties({"message",this.message=}publicvoid o()}14.System.out.println(index+":"+this.index=oImpl3(Stringmessage,intindex)4.privateint一、根據(jù)參數(shù)索引注入,使用“<constructor-argindex="1"value="1"/>”來指二、根據(jù)參數(shù)類型進行注入,使用“<constructor-argtype="java.lang.String"value="oWorld!"/>”來指定注入的依賴,其中“type”表示需要匹配的參數(shù)類型,以是基本類型也可以是其他類型,如“int”、“java.lang.String”,“value”來指定注入的三、根據(jù)參數(shù)名進行注入,使用“<constructor-argname="message"value="oWorld!"/>”來指定注入的依賴,其中“name”表示需要匹配的參數(shù)名字BeanBeanBean來完成上BeanbyIndex”是通過索引注入依賴;BeanbyType”是根據(jù)類型進行注入依賴;Bean”byName”是根據(jù)參數(shù)名字進行注入依賴,具體配置文件java代碼1.1.<!--通過構造器參數(shù)索引方式依賴注入3.<constructor-argindex="0" o5.7.<beanid="byType" <constructor-argtype="int"11.通過構造器參數(shù)名稱方式依賴注入 <constructor-argname="message" o15. <constructor-argname="index"12.<beanid="byName" 10.<constructor-argtype="java.lang.String" o6.<!--通過構造器參數(shù)類型方式依賴注入<constructor-argindex="1"2.<beanid="byIndex" class文件包含“變量信息”,具體查看編譯時是否包含“變量調(diào)試信息”請右擊項目,在彈出的框選擇屬性;然后在彈出的框選擇“JavaCompiler”條目,在“Class文件生成”框中選擇“Class文件(調(diào)試器使用)”3-3-2編譯時打開“添加變量信息選項java代碼1.1.3.BeanFactorybeanFactory=newoApibyIndex=//獲取根據(jù)參數(shù)類型依賴注入的oApibyType=oApibyName=13.12. 10.獲取根據(jù)參數(shù)名字依賴注入的6. 4.//獲取根據(jù)參數(shù)索引依賴注入的2.publicvoidtestConstructorDependencyInjectTest()@java.beans.ConstructorProperties({"message","index"})注解來指定參數(shù)名 oImpl3構造器上把注釋掉的“ConstructorProperties”打開就可以了,這個就留給大家做練習,自己配置然后測試一下。java代碼1.//靜態(tài)工廠2.package3.importcn.javass.spring.chapter2.oworld.4.publicclassDependencyInjectByStaticFactory publicstaticoApinewInstance(Stringmessage,intindex) returnnewoImpl3(message, 8.java代碼1.1.<bean3.<constructor-argindex="0" o5.7.class="cn.javass.spring.chapter3.DependencyInjectByStaticFactory"<constructor-argtype="int"11.<bean<constructor-argname="message" o10.8.<constructor-argtype="java.lang.String" o6.<bean4.<constructor-argindex="1"2.class="cn.javass.spring.chapter3.DependencyInjectByStaticFactory"15.15.<constructor-argname="index"java代碼2.package3.importcn.javass.spring.chapter2.oworld.4.publicclassDependencyInjectByInstanceFactory publicoApinewInstance(Stringmessage,intindex) returnnewoImpl3(message, 8.java代碼1.<bean2.4.<bean5.factory-bean="instanceFactory"factory- <constructor-argindex="0"value="o <constructor-argindex="1"8.9.<bean10.factory-bean="instanceFactory"factory-11.<constructor-argtype="java.lang.String"value="o12.<constructor-argtype="int"13.14.<bean15.factory-bean="instanceFactory"factory-16.<constructor-argname="message"value="o17.<constructor-argname="index"18.class文件中添加“變量調(diào)試信息”方式才能運行,ConstructorProperties不建議使用根setterBean后,通過調(diào)Beansetter3-3所示:3-3setterjava代碼2.import2.importoApipublicoImpl4privateintpublicvoidsetMessage(Stringmessage)}publicvoidsetIndex(intindex)this.message=6.//setter方privateStringthis.index=System.out.println(index+":"+17.}publicvoid o()}java代碼1.1.<!--setter方式進行依賴注入<propertyname="message" o<property<beanid="bean" java代碼1.1.BeanFactorybeanFactoryoApibean=7. 4.new2.publicvoidtestSetterDependencyInject()Springsetter方法?如何將值注入進去的呢?其實方法名是要遵守約定的,setter“JavaBeangetter/setter方法命該類必須要有公共的無參構造器,如publicoImpl4()屬性為private級別,不建議public,如privateStringsetter方法,以“set”開頭,后跟首字母大寫的屬性名,如“setMesssage”,簡getter方法,一般屬性以“get”boolean類型一般以“is”開頭,后setter/getter方法為:“setURL”和“getURL”,其他一些特殊情況請參看“Javajava代碼2.1.<propertyname="message"value="o2.3.<propertyname="index"><value>1</value></property><spanclass="Apple-style-span"style="font-size:14px;white-space:normal;background-color:#ffffff;">Spring容器將此字符串轉換成屬性所需要的類型,如果轉換出錯,將拋出相應Spring容器目前能對各種基本類型把配置的String//假”,所以大家在學習或工作中遇到這種類似問題不要覺得是人家配置錯了,而是java代碼1.2.publicclassBooleanTestBean private publicvoidccess(booleansuccess) = publicbooleanisSuccess() return 10.12.boolean參數(shù)值可以用on/off13.<beanid="bean2" <propertyname="success"15.16.boolean參數(shù)值可以用yes/no17.<beanid="bean3" <propertyname="success"19.20.boolean參數(shù)值可以用1/021.<beanid="bean4" <propertyname="success"23.Bean用于注入Bean的ID,ID是一個常量不是,且類似于注入常量,但提供錯誤驗證功java代碼1.<propertyname="id"><idrefjava代碼1.<propertyname="id"><idrefjava代碼1.<beanid="bean1"2.2.<beanid="idrefBean1"4.3.<propertyname="id"value4.第二種方式(<idrefbean="bean1"/>)可以在容器初始化時校驗被的Bean是否存在,如果不存在將拋出異常,而第式(<idreflocal="bean2"/>)只有在BeanBeanID是否正確,可能發(fā)生不可預料的錯誤。因Bean的ID,推薦使用第二種方式。接下來學下如何使用吧:Bean:java代碼1.package2.publicclassIdRefTestBean privateString publicStringgetId() return publicvoidsetId(Stringid) this.id= 10.其次定義配置文件java代碼1.<beanid="bean1"2.<constructor-argindex="0"3.4.<beanid="bean2" <constructor-argindex="0"6.java代碼1.<beanid="idrefBean1" <propertyname="id"><idref3.4.<beanid="idrefBean2" <propertyname="id"><idref6.Bean的IDjava.lang.String類型,即字符串<idrefbean="……"/>IDBean是否存在,如果不<idreflocal="……"/>XML解析時校驗注入的IDBean在當前配置文件中是否存在,如果不存在將拋出異常,它不同于<idrefbean="……"/>,<idrefSpring不僅能注入簡單類型數(shù)據(jù),還能注入集合(Collection、無序集合Set、有List)類型、數(shù)組(Array)(Map)類型數(shù)據(jù)、Properties類型數(shù)據(jù),接java代碼1.1.package3.publicclassListTestBeanpublicList<String>getValues()}this.values=11.}publicvoidsetValues(List<String>values)returnprivateList<String>2.importBean定義,在配置文件(resources/chapter3/listInject.xml)list注入:java代碼 <property1.<beanid="listBean" <property9.java代碼1.2.publicvoidtestListInject() BeanFactorybeanFactory4.new5.ListTestBeanlistBean=beanFactory.getBean("listBean",6.7.Assert.assertEquals(3,8.Set類型:需要使用<set>來配置注入,其配置參數(shù)及含義和<lsit>完全java代碼1.1.package3.publicclassCollectionTestBeanpublicvoidsetValues(Collection<String>values)}returnpublicCollection<String>getValues()this.values=privateCollection<String>2.import11.11.}Bean定義,在配置文件(resources/chapter3/listInject.xml)list注入:java代碼2.<property1.<beanid="setBean"2.<property..8.9.(2)Collection類型:CollectionSetList類型的基類型,所以使用<set>或<list>都可以進行注入,配置方式完全和以上配置方式一樣,只是將cn.javass.spring.chapter3.DependencyInjectTest測試類中的testCollectionInject測試方法中的代碼?!癱n.javass.spring.chapter3.DependencyInjectTest”testArrayInject<map>來配置注入,其屬性“key-type”和“value-type”分別指定“鍵”和“值”的數(shù)<key>子來指定鍵數(shù)據(jù),<value>子來指定鍵對應的值數(shù)據(jù),具體配置如下“cn.javass.spring.chapter3.DependencyInjectTest”testMapInject測<props>來配置注入,鍵和值類型必須是String,不能變,子<propcn.javass.spring.chapter3.DependencyInjectTest測試類中的testPropertiesInject測試方法中的代碼。之間關系”Bean之間依賴關系,也就是注入依賴 其它BeanBean。Beansetter注入其他Bean,只是其他Bean的注入配置稍微變化了一下:可以將“<constructor-argindex="0"value="oWorld!"/>”和“<propertyname="message"value="oWorld!"/>”中的value屬性替換成bean屬性,其中bean屬性指定配置文件中的其他Bean的id或別名。另一種是把<value>替換為<.refbean=”beanName”>,beanBeanid或別通過”<constructor-arg>”的ref屬性來其他Bean,這是最簡化的配通過”<constructor-arg>”的子<ref>來其他Bean,使用bean屬性來指定的Bean:通過”<property>”的ref屬性來其他Bean,這是最簡化的配置通過”<property>”的子<ref>來其他Bean,使用bean屬性來指定的Bean:首先讓我們定義測試Bean的類,在此我們可以使用原有的oApi實現(xiàn),然后再定義一個裝飾器來其他Bean,具體裝飾類如下:java代碼packageimport public}oApiDecoratoroApioApiDecorator()oApi)oApi11.12.publicvoid oApioApi)21.}publicvoido()}定義好了測試Bean接下來該在配置文件(resources/chapter3/beanInject.xml)進行配置BeansetterBean:java代碼3.<!--通過構造器注入3.<!--通過構造器注入5.<constructor-argindex="0" 7.<!--通過構造器注入<property oApi"><ref10.8.<beanid="bean2" 6.4.<beanid="bean1" 2.<bean oApi" java代碼1.1.BeanFactorybeanFactoryoApibean1=oApibean2=11. //通過setter4.new2.publicvoidtestBeanInject()四、其他方式:除了最基本配置方式以外,Spring還提供了另外兩種更高級的配置方式,<reflocal=””/>和<refparent=””/>:<reflocal=””/>配置方式:用于通過<beanid=”beanName”>方式中通過id屬性指定的Bean,它能利用XML解析器的驗證功能在配置文件時來驗證引用的Bean是否存在。因此如果在當前配置文件中有相互的Bean可以采用<refLine21inXML fromclasspathresource[chapter3/beanInject2.xml]isinvalid;nestedexceptionisorg.xml.sax.SAXParseException:cvc-id.1:ThereisnoID/IDREFbindingforIDREF'oApi'.<reflocal><refparent=””/>配置方式:用于父容器中的Bean,不會當前容BeanBean和當前容器的Bean首先還是準備測試類,在此我們就使用以前寫好的oApiDecorator和oImpl4類;其次進行Bean定義,其中當前容器bean1本地的”oApi”,而”bean2”將引java代碼1.<!--sources/chapter3/parentBeanInject.xml表示父容器配置2.<!--注意此處可能子容器也定義一個該Bean3.<beanid="oApi"class="cn.javass.spring.chapter3.4.<propertyname="index"5.<propertyname="message"value="o6.java代碼2.<!--注意父容器中也定義了id 2.<!--注意父容器中也定義了id oApi的Bean--<propertyname="message" o7.<!--local注<propertyname="message" o7.<!--local注入9.<constructor-argindex="0"><ref 11.parent注入13.<property oApi"><ref 14.12.<beanid="bean2" 10.8.<beanid="bean1" 6.4.<propertyname="index"java代碼1.2.publicvoidtestLocalAndparentBeanInject()3.//4.ApplicationContextparentBeanContext5.new6.//初始化當前容7.ApplicationContextbeanContext=new8.newString[]{"chapter3/localBeanInject.xml"}, oApibean1=beanContext.getBean("bean1", o();//該 local 11.oApibean2=beanContext.getBean("bean2",12.o();//該parent13.“bean1”將輸出“oLocal!”表示當前容器的Bean,”bean2”將輸出“oParen!”,表示父容器的Bean,如配置有問題請參考cn.javass.spring.chapter3.DependencyInjectTest中的Bean定內(nèi)部Bean就是在<property>或<constructor-arg>內(nèi)通過<bean>定義的Bean,該Bean不管是否指定id或name,該Bean都會有唯一的標識符,而且不BeanBean不可見,具體配置如下:java代碼1.1.<beanid="bean" 3.<bean oApi" 5.4.2.<property java代碼1.1.3.ApplicationContextcontextoApibean=7.6. 4.new2.publicvoidtestInnerBeanInject()nullSpring通過<value>或value屬性注入常量值,所有注入的數(shù)據(jù)都是字符null“null”值嗎?當然不是因為如果注入“null”則認為是字符串。Spring通過<null/>注入null值。即可以采用如下配置方式:a.b.c對象導航圖注入ab必須為非null值才能注入c,否則將拋出空指針異常。Set數(shù)據(jù)類型無法支持,因為無法導航。array[0]、list[1]導航,注意”[]”里的必須是數(shù)字,因為是按Map數(shù)據(jù)類型可以使用map[1]、map[str]進行導航,其中“[]”里的是基本類型,無法放置類型。讓我們來練下吧。首先準備測試類,在此我們需要三個測試類,以便實現(xiàn)對象java代碼1.package2.publicclassNavigationC publicvoidsayNavigation() }}NavigationB類,包含對象和列表、Properties、數(shù)組字典數(shù)據(jù)類型導航,而且這些java代碼1.package2.import3.import4.import5.publicclassNavigationB privateNavigationC privateList<NavigationC> privateProperties privateNavigationC[]array=new privateMap<String,NavigationC> //setter和getter12.java代碼1.package2.publicclassNavigationA privateNavigationB publicvoidsetNavigationB(NavigationBnavigationB) = publicNavigationBgetNavigationB() return 10.(rsurcschr3/nviionnnc.ml)NviionC和NviionBNviionBrryNvonCrry=nwNvonC”ss如下:java代碼1.<beanid="c"2.<beanid="b"3.<property <property <property6.需要注意,由于“navigationB”“navigationB”值;還有java代碼2.<!--首先注入navigatiionB確保它非空2.<!--首先注入navigatiionB確保它非空3.<propertyname="navigationB"4.4.<!--對象圖導航注入6.<!--注入列表數(shù)據(jù)類型數(shù)據(jù)5.<property6.<!--注入列表數(shù)據(jù)類型數(shù)據(jù)7.<propertyname="navigationB.list[0]"8.8.<!--map類型數(shù)據(jù)10.properties類型數(shù)據(jù)10.properties類型數(shù)據(jù)11.<propertyname="navigationB.properties[0]"14.注入數(shù)組類型數(shù)據(jù),注意不要越界13.<property14.注入數(shù)組類型數(shù)據(jù),注意不要越界15.<propertyname="navigationB.array[0]"16.16.java代碼2.1.//對象圖導2.3.publicvoidtestNavigationBeanInject()4.ApplicationContextcontext5.new6.NavigationAnavigationA=context.getBean("a",.5個“===navigationc”,是不是很簡單,注意這種方式是不3.1.5一節(jié)使用的配置方式。配置簡1)全寫:<constructor-argindex="0"><value>常量</value></constructor-arg>2)簡寫:<constructor-argindex="0"ref="全寫:<constructor-argindex="0"><refbean=""/></constructor-"></簡寫:<propertyname="message"ref="全寫:<propertyname="message"><refbean=""/></property><entrykey="鍵常量value="值常量<entrykey-ref="鍵"value-ref="值><<entry><key><refbean="鍵"/></key><refbean="值java代碼2.<beans"1.<?xml2.<beans"""<constructor-argindex="0"11.<beanid="idrefBean1"13.<beanid="idrefBean2"15.14.p:id-12.8.<beanid="bean1" p<beanidclassp:id="value:常量setter注入方式,其等價于<propertyname="id"<beanid="……"class="……"p:id-ref="bean1"/>:setter注入方式,其等價于<propertyname="id"CircleB,CircleBCircleC,CircleCCircleA,則它們最終反映為一個3-5Spring容器循環(huán)依賴包括構造器循環(huán)依賴和setter循環(huán)依賴,那Spring容器如何解決循環(huán)依賴呢?首先讓我們來定義循環(huán)類:java代碼1.package2.blicclassCircleAprivateCircleBpublicCircleA()} publicCircleA(CircleBcircleB) this.circleB=}9.publicvoidsetCircleB(CircleB10. this.circleB= 13.publicvoida() 15.16.java代碼1.1.packageprivateCircleC}this.circleC=9.publicvoidsetCircleC(CircleCthis.circleC=publicvoidb()}}10.}publicCircleB(CircleCcircleC)publicCircleB()2.publicclassCircleB16.16.java代碼package2.blicclassCircleCprivateCircleApublicCircleC()} publicCircleC(CircleAcircleA) this.circleA=}9.publicvoidsetCircleA(CircleA10. this.circleA= publicvoidc() 16.SpringBeanCurrentlyInCreationException異常表示循環(huán)依賴。如在創(chuàng)建CircleA類時,構造器需要CircleB類,那將去創(chuàng)建CircleB,在創(chuàng)建CircleBCircleC類,則又去創(chuàng)建CircleC,最終在創(chuàng)建CircleC時發(fā)現(xiàn)又需要SpringBean標識符放在一個“Bean池”中,BeanBean過程中發(fā)現(xiàn)自己已經(jīng)在“Bean池”BeanCurrentlyInCreationException異常表示循環(huán)Bean將從“當前創(chuàng)建Bean池”中清除掉。java代碼1.1.<beanid="circleA"<constructor-argindex="0"3.4.<beanid="circleB"5.<constructor-argindex="0"6.7.<beanid="circleC"8.<constructor-argindex="0"9.java代碼1.1.@Test(expected=3.try}//因為要在創(chuàng)建circle3時拋出throw11.}Throwablee1=catch(Exceptione) new2.publicvoidtestCircleByConstructor()throwsThrowable1、Spring容器創(chuàng)建“circleABean,首先去“Bean池”查找是否當前Bean正在創(chuàng)建,如果沒發(fā)現(xiàn),則繼續(xù)準備其需要的構造器參數(shù)“circleB”,并將“circleA”標識符放到“Bean池”;2、Spring容器創(chuàng)建“circleBBean,首先去“Bean池”查找是否當前Bean正在創(chuàng)建,如果沒發(fā)現(xiàn),則繼續(xù)準備其需要的構造器參數(shù)“circleC”,并將“circleB”標識符放到“Bean池”;在創(chuàng)建,如果沒發(fā)現(xiàn),則繼續(xù)準備其需要的構造器參數(shù)“circleA”,并將“circleC”標識符放到“Bean池”;對于setter注入造成的依賴是通過Spring容器提前剛完成構造器注入但未完成其他步驟(setter注入)BeanBean循環(huán)依賴。java代碼1.addSingletonFactory(beanName,newObjectFactory() publicObjectgetObject()throwsBeansException returngetEarlyBeanReference(beanName,mbd, 5.1、Spring容器創(chuàng)建單例“circleABeanBean,并暴露一個“ObjectFactory”用于返回一個提前一個創(chuàng)建中的Bean,并將“circleA”標識符放到“Bean池”setter注入“circleB”;2、Spring容器創(chuàng)建單例“circleB”BeanBean,并暴露一個“ObjectFactory”用于返回一個提前一個創(chuàng)建中的Bean,并將“circleB”標識符放到“Bean池”setter注入“circleC”;3、Spring容器創(chuàng)建單例“circleC”BeanBean,并暴露一個“ObjectFactory”用于返回一個提前一個創(chuàng)建中的Bean,并將“circleC”標于提前了“ObjectFactory”工廠從而使用它返回提前一個創(chuàng)建中的Bean;作用域的Bean,Spring容器不進行緩存,因此無法提前一個創(chuàng)建中的Bean。java代碼1.<!--Bean配置文件,注意scope都是“prototype2.<beanid="circleA"class="cn.javass.spring.chapter3.bean.CircleA" <propertyname="circleB" <beanid="circleB"class="cn.javass.spring.chapter3.bean.CircleB" <propertyname="circleC" <beanid="circleC"class="cn.javass.spring.chapter3.bean.CircleC" <propertyname="circleA" java代碼 測試代 3.publicvoidtestCircleBySetterAndPrototype()throwsThrowableClassPathXmlApplicationContextctx=newcatch(Exceptione)throw13.}Throwablee1=}6.try2.@Test(expected=java代碼1.1.@Test(expected=try5.newClassPathXmlApplicationContextctx2.publicvoidtestCircleBySetterAndSingleton2()throwsThrowable catch(Exceptione) Throwablee1= throw 13.(DAGDIBean。配置方式很簡單只需在<bean>上指定“l(fā)azy-init”屬性值為“true”即可延遲Bean。Spring容器會在創(chuàng)建容器時提前初始化“singleton”作用域的Bean,“singleton”Bean只有一個實例,后邊會詳細介紹。Spring容器預Bean通常能幫助我們提前發(fā)現(xiàn)配置錯誤,所以如果沒有什么情況建議開啟,除BeanBean時被初始化,因為在這時使用了延遲初始化Bean消除了編程實現(xiàn)延遲初始化,完全由容器控制,只需在需要Bean定義上配置即可,比編程方式更簡單,而且是無侵入代碼的。jav

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論