火龍果Spring框架教學(xué)課件ppt_第1頁
火龍果Spring框架教學(xué)課件ppt_第2頁
火龍果Spring框架教學(xué)課件ppt_第3頁
火龍果Spring框架教學(xué)課件ppt_第4頁
火龍果Spring框架教學(xué)課件ppt_第5頁
已閱讀5頁,還剩90頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

Spring企業(yè)開發(fā)

Spring是什么Spring是一個開源的控制反轉(zhuǎn)(InversionofControl,IoC)和面向切面(AOP)的容器框架.它的主要目的是簡化企業(yè)開發(fā).IOC控制反轉(zhuǎn)publicclassPersonService{//服務(wù)層

privatePersonDaopersonDao=new

PersonDaoBean();

publicvoidsave(Personperson){//保存一個對象personDao.save(person);}}PersonDaoBean是在應(yīng)用內(nèi)部創(chuàng)建及維護的(在PersonService類中new出來的)。所謂控制反轉(zhuǎn)就是應(yīng)用本身不負(fù)責(zé)依賴對象的創(chuàng)建及維護,依賴對象的創(chuàng)建及維護是由外部容器負(fù)責(zé)的。這樣控制權(quán)就由應(yīng)用轉(zhuǎn)移到了外部容器,控制權(quán)的轉(zhuǎn)移就是所謂反轉(zhuǎn)。依賴注入(DependencyInjection)當(dāng)我們把依賴對象交給外部容器負(fù)責(zé)創(chuàng)建,那么PersonService類可以改成如下:publicclassPersonService{

privatePersonDaopersonDao;

//通過構(gòu)造器參數(shù),讓容器把創(chuàng)建好的依賴對象注入進PersonService,當(dāng)然也可以使用setter方法進行注入。

publicPersonService(PersonDaopersonDao){this.personDao=personDao;}

publicvoidsave(Personperson){personDao.save(person);}}所謂依賴注入就是指:在運行期,由外部容器動態(tài)地將依賴對象注入到組件中。為何要使用Spring在項目中引入spring立即可以帶來下面的好處降低組件之間的耦合度,實現(xiàn)軟件各層之間的解耦。

可以使用容器提供的眾多服務(wù),如:事務(wù)管理服務(wù)、消息服務(wù)等等。當(dāng)我們使用容器管理事務(wù)時,開發(fā)人員就不再需要手工控制事務(wù).也不需處理復(fù)雜的事務(wù)傳播。容器提供單例模式支持,開發(fā)人員不再需要自己編寫實現(xiàn)代碼。容器提供了AOP技術(shù),利用它很容易實現(xiàn)如權(quán)限攔截、運行期監(jiān)控等功能。容器提供的眾多輔作類,使用這些類能夠加快應(yīng)用的開發(fā),如:JdbcTemplate、HibernateTemplate。Spring對于主流的應(yīng)用框架提供了集成支持,如:集成Hibernate、JPA、Struts等,這樣更便于應(yīng)用的開發(fā)。ControllerServiceDAO使用Spring的好處當(dāng)使用spring時,我們可以使用容器提供的眾多服務(wù)

如果使用Spring,我們就不再需要手工控制事務(wù)publicvoidsavePerson(){Peoplepeople=newPeople();people.setCardNo();people.setName("李四");try{ session.save(people); mit();}catch(HibernateExceptione){ transaction.rollback(); e.printStackTrace();}}使用Hibernate框架需要手工提交事務(wù)另外,如果使用spring,我們也不需要處理復(fù)雜的事務(wù)傳播行為publicvoidpayment(){Bean1.update();//更新金額Bean2.save();//記錄操作日志}如果我們不使用Spring,針對下面這兩種業(yè)務(wù)需求,我們該如何做?第1種可能的業(yè)務(wù)需求:要求Bean1.update()和Bean2.save()在同一個事務(wù)中執(zhí)行。第2種可能的業(yè)務(wù)需求:要求不管Bean1.update()的事務(wù)是否成功,都需要記錄操作日志。publicclassBean1{

publicvoidupdate(){//注意:下面省略了一些代碼 Connectionconn=null; conn.setAutoCommit(false);

Statement.executeUpdate(“updateaccountsetamount=?whereid=?");

}}publicclassBean2{

publicvoidsave(){//注意:下面省略了一些代碼 Connectionconn=null; conn.setAutoCommit(false);

Statement.executeUpdate(“insertintoLog(content)values(?)");

}}使用Spring,不再需要我們處理復(fù)雜的事務(wù)傳播行為使用Spring,我們只需要通過聲明式的事務(wù)屬性配置就可以輕松地實現(xiàn)這兩種業(yè)務(wù)需求1.要求Bean1.update()和Bean2.save()的在同一個事務(wù)中執(zhí)行2.要求不管Bean1.update()的事務(wù)是否成功,都需要記錄日志。@Transactional(propagation=Propagation.Required)publicvoidpayment(){Bean1.update();//更新金額Bean2.save();//記錄日志}

publicclassBean1{@Transactional(propagation=Propagation.Required)

publicvoidupdate(){

executeUpdate(“updateaccountsetamount=?whereid=?");

}}publicclassBean2{

@Transactional(propagation=Propagation.RequiresNew)

publicvoidsave(){ executeUpdate(“insertintoLog(content)values(?)");}}輕量級與重量級概念的劃分經(jīng)常會有同學(xué)問到spring屬于輕量級框架,還是重量框架?其實劃分一個應(yīng)用是否屬于輕量級還是重量級,主要看它使用了多少服務(wù).使用的服務(wù)越多,容器要為普通java對象做的工作就越多,必然會影響到應(yīng)用的發(fā)布時間或者是運行性能.對于spring容器,它提供了很多服務(wù),但這些服務(wù)并不是默認(rèn)為應(yīng)用打開的,應(yīng)用需要某種服務(wù),還需要指明使用該服務(wù),如果應(yīng)用使用的服務(wù)很少,如:只使用了spring核心服務(wù),那么我們可以認(rèn)為此時應(yīng)用屬于輕量級的,如果應(yīng)用使用了spring提供的大部分服務(wù),這時應(yīng)用就屬于重量級。目前EJB容器就因為它默認(rèn)為應(yīng)用提供了EJB規(guī)范中所有的功能,所以它屬于重量級。使用Spring需要的jar到/download下載spring,然后進行解壓縮,在解壓目錄中找到下面jar文件,拷貝到類路徑下dist\spring.jarlib\jakarta-commons\commons-logging.jar如果使用了切面編程(AOP),還需要下列jar文件lib/aspectj/aspectjweaver.jar和aspectjrt.jarlib/cglib/cglib-nodep-2.1_3.jar如果使用了JSR-250中的注解,如@Resource/@PostConstruct/@PreDestroy,還需要下列jar文件lib\j2ee\common-annotations.jar本次課程使用的Spring版本是2.5使用myeclipse添加Spring應(yīng)用第一步:創(chuàng)建web工程(其實普通j2se工程也可以)使用myeclipse添加Spring應(yīng)用第二步:在web工程中添加Spring框架支持使用myeclipse添加Spring應(yīng)用這里只是簡單應(yīng)用,沒有涉及到和其它框架的集成,因此選擇前面兩個就可以了。使用myeclipse添加Spring應(yīng)用這步的目的是生成Spring配置文件applicationContext.xml文件位置是src使用myeclipse添加Spring應(yīng)用框架添加完成之后的效果使用myeclipse添加Spring應(yīng)用publicclassUserInfo{privateIntegerid;privateStringname;privateStringaddress;privateIntegerage;//setandgetmethod……}第三步:創(chuàng)建一個實體類;并生成屬性對應(yīng)的set/get方法使用myeclipse添加Spring應(yīng)用第四步:根據(jù)左邊的實體類屬性名稱和數(shù)據(jù)類型在Spring配置文件中配置一個bean;這個bean的id值是userInfoBean這個id屬性名稱對應(yīng)的值在applicationContext.xml必須是唯一;不能存在同名;在應(yīng)用程序中將根據(jù)id名稱來獲取這個bean使用myeclipse添加Spring應(yīng)用//編寫測試類,從Spring容器中獲取userInfoBeanpackage.chongking;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassBeanUtil{publicstaticvoidmain(String[]args){ ApplicationContextcontext= newClassPathXmlApplicationContext("applicationContext.xml"); UserInfouserInfo=(UserInfo)context.getBean(“normalBean"); System.out.println(userInfo.getName()+":"+userInfo.getAddress());}}第五步:編寫測試類;從spring容器中根據(jù)bean的id獲取bean對象userInfoBean是applicationContext.xml配置文件中的beanid屬性值applicationContext.xml<beanid="normalBean"class=".chongking.UserInfo"><propertyname="id"value="1"/><propertyname="name"value="李四"/><propertyname="address"value="柳州"/><propertyname="age"value="22"/></bean>使用eclipse添加Spring應(yīng)用使用eclipse開發(fā)Spring應(yīng)用需要自己添加使用到的jar文件和spring配置文件(applicationContext.xml)其它的配置和測試跟使用myeclipse是一樣的。在java體系中絕大部分的框架應(yīng)用所涉及到的引用基本上都是jar文件和配置文件。Jar文件和配置文件有多種渠道可以獲取;可以從官方網(wǎng)站上下載;可以使用別人現(xiàn)有的;可以通過其它渠道獲取。spring的配置文件模版<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-2.5.xsd">

</beans>該配置模版可以從spring的參考手冊或spring的例子中得到。配置文件的取名可以任意,文件可以存放在任何目錄下,但考慮到通用性,一般放在類路徑下。編寫spring配置文件時,不能出現(xiàn)幫助信息由于spring的schema文件位于網(wǎng)絡(luò)上,如果機器不能連接到網(wǎng)絡(luò),那么在編寫配置信息時候就無法出現(xiàn)提示信息,解決方法有兩種:1。讓機器上網(wǎng),eclipse會自動從網(wǎng)絡(luò)上下載schema文件并緩存在硬盤上。2。手動添加schema文件,方法如下:windwos->preferences->myeclipse->filesandeditors->xml->xmlcatalog點"add",在出現(xiàn)的窗口中的KeyType中選擇URI,在location中選"Filesystem",然后在spring解壓目錄的dist/resources目錄中選擇spring-beans-2.5.xsd,回到設(shè)置窗口的時候不要急著關(guān)閉窗口,應(yīng)把窗口中的KeyType改為Schemalocation,Key改為/schema/beans/spring-beans-2.5.xsd實例化spring容器實例化Spring容器常用的兩種方式:方法一:在類路徑下尋找配置文件來實例化容器ApplicationContextctx=newClassPathXmlApplicationContext(newString[]{"beans.xml"});方法二:在文件系統(tǒng)路徑下尋找配置文件來實例化容器ApplicationContextctx=newFileSystemXmlApplicationContext(newString[]{“d:\\beans.xml“});Spring的配置文件可以指定多個,可以通過String數(shù)組傳入。從spring容器中得到bean當(dāng)spring容器啟動后,因為spring容器可以管理bean對象的創(chuàng)建,銷毀等生命周期,所以我們只需從容器直接獲取Bean對象就行,而不用編寫一句代碼來創(chuàng)建bean對象。從容器獲取bean對象的代碼如下:ApplicationContextctx=newClassPathXmlApplicationContext(“beans.xml”);OrderServiceservice=(OrderService)ctx.getBean("personService");使用dom4j讀取spring配置文件publicclassClassPathXmlApplicationContext{

privateList<BeanDefinition>beanDefines=newArrayList<BeanDefinition>();

publicApplicationContext(Stringfilename){ init(filename);}

privatevoidinit(Stringfilename){SAXReadersaxReader=newSAXReader();Documentdocument=null;try{URLxmlpath=this.getClass().getClassLoader().getResource(filename);document=saxReader.read(xmlpath);Map<String,String>nsMap=newHashMap<String,String>();nsMap.put("ns","/schema/beans");//加入命名空間

XPathxsub=document.createXPath("http://ns:beans/ns:bean");//創(chuàng)建beans/bean查詢路徑

xsub.setNamespaceURIs(nsMap);//設(shè)置命名空間

List<Element>beans=xsub.selectNodes(document);//獲取文檔下所有bean節(jié)點

for(Elementelement:beans){Stringid=element.attributeValue("id");//獲取id屬性值

Stringclazz=element.attributeValue("class");//獲取class屬性值

BeanDefinitionbeanDefine=newBeanDefinition(id,clazz);beanDefines.add(beanDefine);}}catch(Exceptione){e.printStackTrace();}}}三種實例化bean的方式-使用類構(gòu)造器實例化//實體類設(shè)計publicclassUserInfo{privateIntegerid;privateStringname;privateStringaddress;privateIntegerage;//構(gòu)造子publicUserInfo(){}//構(gòu)造子publicUserInfo(Integerid,Stringname, Stringaddress,Integerage){ this.id=id; =name; this.address=address; this.age=age;}//setandgetmethod…}applicationContext.xml配置<beanid="normalBean" class=".chongking.UserInfo"> <propertyname="id"value="1"/> <propertyname="name"value="李四"/> <propertyname="address"value="柳州"/> <propertyname="age"value="22"/></bean>//從Spring容器獲取Bean測試代碼publicvoidgetUserInfo(){ UserInfouserInfo= (UserInfo)context.getBean("normalBean"); System.out.println(userInfo.getId()+": "+userInfo.getName()+":"+userInfo.getAddress());}三種實例化bean的方式-使用靜態(tài)工廠方法實例化//工廠類設(shè)計publicclassBeanFactory{publicstaticUserInfofactoryDao(){returnnewUserInfo(1,"王五","南寧",21);}}applicationContext.xml配置<beanid="staticFactoryBean" class=".chongking.BeanFactory"

factory-method="factoryDao"/>publicvoidstaticFactoryBean(){//測試代碼 UserInfouserInfo=(UserInfo)context.getBean("staticFactoryBean"); System.out.println(userInfo.getId()+": "+userInfo.getName()+":"+userInfo.getAddress());}//實體類設(shè)計publicclassUserInfo{privateIntegerid;privateStringname;privateStringaddress;privateIntegerage;//構(gòu)造子publicUserInfo(){}//構(gòu)造子publicUserInfo(Integerid,Stringname, Stringaddress,Integerage){ this.id=id; =name; this.address=address; this.age=age;}//setandgetmethod…}三種實例化bean的方式-使用實例工廠方法實例化//工廠類設(shè)計publicclassBeanFactory{publicUserInfocreateUserInfo(){returnnewUserInfo(1,"王五","南寧",21);}}applicationContext.xml配置<beanid="factoryBean"class=".chongking.BeanFactory"/><beanid="instanceFactoryBean"factory-bean="factoryBean"factory-method="createUserInfo"/>//使用實例工廠方法實例化測試publicvoidinstanceFactoryBean(){UserInfouserInfo=(UserInfo)context.getBean("instanceFactoryBean");System.out.println(userInfo.getId()+":"+userInfo.getName()+":"+userInfo.getAddress());}Bean的作用域(scope屬性).singleton

在每個SpringIoC容器中一個bean定義只有一個對象實例。默認(rèn)情況下會在容器啟動時初始化bean,但我們可以指定Bean節(jié)點的lazy-init=“true”來延遲初始化bean,這時候,只有第一次獲取bean會才初始化bean。如:

<beanid="xxx"class=".chongking.OrderServiceBean"lazy-init="true"/>如果想對所有bean都應(yīng)用延遲初始化,可以在根節(jié)點beans設(shè)置default-lazy-init=“true“,如下:<beansdefault-lazy-init="true“...>可以通過在構(gòu)造函數(shù)中輸出信息來跟蹤.prototype

每次從容器獲取bean都是新的對象。.request.session.globalsessionrequest,session,globalsession是針對web程序而言的指定Bean的初始化方法和銷毀方法指定Bean的初始化方法和銷毀方法<beanid="xxx"class=".chongking.OrderServiceBean"init-method="init"destroy-method="close"/>importorg.junit.*;importorg.springframework.context.support.AbstractApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassBeanUtil{AbstractApplicationContextcontext=null;//Spring容器對象(注意:不是ApplicationContext)@Beforepublicvoidbefore(){System.out.println("before...");context=newClassPathXmlApplicationContext("applicationContext.xml");}@TestpublicvoidgetEmployeeBean(){

//Employee類中有兩個方法:init();和close()Employeeemployee=(Employee)context.getBean("empBean");System.out.println(employee.getName());}@Afterpublicvoidafter(){

context.close();//需要顯示調(diào)用}}注入依賴對象-基本類型對象注入<beanid="empBean"class=".chongking.Employee"><propertyname="id"value="1"/><propertyname="name"value="李四"/><propertyname="address"value="柳州"/></bean>publicclassEmployee{//實體類設(shè)計privateIntegerid;privateStringname;privateStringaddress;publicEmployee(){System.out.println("不帶參數(shù)的構(gòu)造方法");}publicEmployee(Integerid,Stringname,Stringaddress){System.out.println("帶參數(shù)構(gòu)造函數(shù)");this.id=id;=name;this.address=address;}//setandgetmethod注入依賴對象-構(gòu)造器注入applicationContext.xml配置<beanid="empBean"class=".chongking.Employee"><constructor-argindex="0"type="java.lang.Integer"value="1"/><constructor-argindex="1"type="java.lang.String"value="李四"/><constructor-argindex="2"type="java.lang.String"value="桂林"/></bean>實體類構(gòu)造方法publicEmployee(Integer

id,String

name,String

address){System.out.println("帶參數(shù)構(gòu)造函數(shù)");this.id=id;=name;this.address=address;}@TestpublicvoidgetEmployeeBean(){//測試方法Employeeemployee=(Employee)context.getBean("empBean");System.out.println(employee.getId()+":"+employee.getName()+":"+employee.getAddress());}注入依賴對象-注入其它Bean-1applicationContext.xml配置<beanid="cpuBean"class=".chongking.Cpu"/><beanid="computerBean"class=".chongking.Computer"><propertyname="cpu"ref="cpuBean"/></bean>publicclassCpu{publicvoidhardwareInfo(){System.out.println("AMD速龍");}}@TestpublicvoidgetComputer(){//測試類

Computercomputer=

(Computer)context.getBean("computerBean");

computer.testCput();}publicclassComputer{privateCpucpu;//set方法是必須的(set注入)publicvoidsetCpu(Cpucpu){this.cpu=cpu;}publicCpugetCpu(){returncpu;}publicvoidtestCput(){cpu.hardwareInfo();}}注入依賴對象-注入其它Bean-2applicationContext.xml配置<beanid="computerBean"class=".chongking.Computer"><propertyname="cpu"><beanclass=".chongking.Cpu"/></property></bean>publicclassCpu{publicvoidhardwareInfo(){System.out.println("AMD速龍");}}@TestpublicvoidgetComputer(){//測試類

Computercomputer=

(Computer)context.getBean("computerBean");

computer.testCput();}publicclassComputer{privateCpucpu;//set方法是必須的(set注入)publicvoidsetCpu(Cpucpu){this.cpu=cpu;}publicCpugetCpu(){returncpu;}publicvoidtestCput(){cpu.hardwareInfo();}}使用內(nèi)部bean,但該bean不能被其他bean使用練習(xí)-通過Bean注入模擬計算機組裝//接口設(shè)計publicinterfaceUSB{//USB接口信息publicvoidinfo(Stringcontent);}publicinterfaceIprint{//打印機接口信息publicvoidinfo(Stringcontent);}publicclassMemory{//內(nèi)存類publicvoidinfo(Stringconfig){System.out.println("內(nèi)存配置:"+config);}}publicclassComputer{//計算機類privateUSBusb;privateIprintprint;privateMemorymemory;publicvoidshowHardWareInfo(){("移動硬盤");("彩色打印機");("金士頓內(nèi)存條");}//省略了set、get方法}applicationContext.xml配置<beanid="uDisk"class="puter.UDisk"/><beanid="colorPrint"class="puter.ColorPrint"/><beanid="memory"class="puter.Memory"/><beanid="computerBean"class="puter.Computer"><propertyname="usb"ref="uDisk"/><propertyname="print"ref="colorPrint"/><propertyname="memory"ref="memory"/></bean>@TestpublicvoidgetComputer(){//模擬計算機組裝測試方法Computercomputer=(Computer)context.getBean("computerBean");computer.showHardWareInfo();}//接口實現(xiàn)類publicclassUDiskimplementsUSB{publicvoidinfo(Stringconfig){System.out.println("usb接口配置:"+config);}}publicclassColorPrintimplementsIprint{publicvoidinfo(Stringconfig){System.out.println("彩色打印機:"+config);}}集合類型的裝配<beanid="order"class=".chongking.Order"><propertyname="lists"><list><value>cjkj</value></list></property> <propertyname="sets"><set><value>set</value></set></property> <propertyname="maps"><map><entrykey=“l(fā)isi"value="28"/></map></property> <propertyname="properties"><props> <propkey="12">cjkj</prop></props></property></bean>@TestpublicvoidgetOrder(){//測試類Orderorder=(Order)context.getBean("order");List<String>lists=order.getLists();for(Strings:lists){System.out.println(s);}}publicclassOrder{privateSet<String>sets=newHashSet<String>();privateList<String>lists=newArrayList<String>();privatePropertiesproperties=newProperties();privateMap<String,String>maps=newHashMap<String,String>();//這里省略屬性的getter和setter方法}依賴注入使用構(gòu)造器注入使用屬性setter方法注入使用Field注入(用于注解方式)注入依賴對象可以采用手工裝配或自動裝配,在實際應(yīng)用中建議使用手工裝配,因為自動裝配會產(chǎn)生未知情況,開發(fā)人員無法預(yù)見最終的裝配結(jié)果。1.手工裝配依賴對象2.自動裝配依賴對象依賴注入--手工裝配手工裝配依賴對象,在這種方式中又有兩種編程方式1.在xml配置文件中,通過在bean節(jié)點下配置,如<beanid="orderService"class=".chongking.People"><constructor-argindex=“0”type=“java.lang.Integer”value=“1”/>//構(gòu)造器注入(帶參構(gòu)造函數(shù)第1個值)

<constructor-argindex=“1”type=“java.lang.String”value=“李四”/>//構(gòu)造器注入(帶參構(gòu)造函數(shù)第2個值)<constructor-argindex=“2”type=“java.lang.String”value=“柳州”/>//構(gòu)造器注入(帶參構(gòu)造函數(shù)第3個值)

<propertyname=“name”value=“李四”/>//屬性setter方法注入</bean>2.在java代碼中使用@Autowired或@Resource注解方式進行裝配。但我們需要在xml配置文件中配置以下信息:<beansxmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"

xmlns:context="/schema/context"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-2.5.xsd

/schema/context/schema/context/spring-context-2.5.xsd">

<context:annotation-config/></beans>這個配置隱式注冊了多個對注釋進行解析處理的處理器:AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor注:@Resource注解在spring安裝目錄的lib\j2ee\common-annotations.jar依賴注入--手工裝配在java代碼中使用@Autowired或@Resource注解方式進行裝配,這兩個注解的區(qū)別是:@Autowired默認(rèn)按類型裝配,@Resource默認(rèn)按名稱裝配,當(dāng)找不到與名稱匹配的bean才會按類型裝配。

@AutowiredprivatePersonDaopersonDao;//用于字段上@AutowiredpublicvoidsetOrderDao(OrderDaoorderDao){//用于屬性的setter方法上this.orderDao=orderDao;}@Autowired注解是按類型裝配依賴對象,默認(rèn)情況下它要求依賴對象必須存在,如果允許null值,可以設(shè)置它required屬性為false@Autowired(required=false)。如果我們想使用按名稱裝配,可以結(jié)合@Qualifier注解一起使用。如下:@Autowired@Qualifier("personDaoBean")privatePersonDaopersonDao;@Resource注解和@Autowired一樣,也可以標(biāo)注在字段或?qū)傩缘膕etter方法上,但它默認(rèn)按名稱裝配。名稱可以通過@Resource的name屬性指定,如果沒有指定name屬性,當(dāng)注解標(biāo)注在字段上,即默認(rèn)取字段的名稱作為bean名稱尋找依賴對象,當(dāng)注解標(biāo)注在屬性的setter方法上,即默認(rèn)取屬性名作為bean名稱尋找依賴對象。

@Resource(name=“personDaoBean”)privatePersonDaopersonDao;//用于字段上注意:如果沒有指定name屬性,并且按照默認(rèn)的名稱仍然找不到依賴對象時,@Resource注解會回退到按類型裝配。但一旦指定了name屬性,就只能按名稱裝配了。依賴注入--手工裝配-注解裝配AutowiredpublicclassComputer{//計算機類

@AutowiredprivateUSBusb;

@AutowiredprivateIprintprint;

@AutowiredprivateMemorymemory;publicvoidshowHardWareInfo(){("移動硬盤");("彩色打印機");("金士頓內(nèi)存條");}//不用再寫set、get方法}bean.xml配置<beanid="uDisk"class="puter.UDisk"/><beanid="colorPrint"class="puter.ColorPrint"/><beanid="memory"class="puter.Memory"/><beanid="computerBean"class="puter.Computer"><!–

不用再配置computerBean中引用的bean<propertyname="usb"ref="uDisk"/><propertyname="print"ref="colorPrint"/><propertyname="memory"ref="memory"/>--></bean>@TestpublicvoidgetComputer(){//模擬計算機組裝測試方法Computercomputer=(Computer)context.getBean("computerBean");computer.showHardWareInfo();}與xml配置文件中配置引用的Bean的區(qū)別是:ComputerBean中不用再配置引用的Bean;這是優(yōu)點;缺點是還是要在spring配置文件中配置uDisk,colorPrint,memory,computerBean這些Bean依賴注入--手工裝配-注解裝配ResourcepublicclassComputer{privateUSBusb;privateIprintprint;privateMemorymemory;publicvoidshowHardWareInfo(){

("移動硬盤");

("彩色打印機");

("金士頓內(nèi)存條");}@Resource(name="uDisk")publicvoidsetUsb(USBusb){

this.usb=usb;}@Resource(name="colorPrint")publicvoidsetPrint(Iprintprint){

this.print=print;}@Resource(name="memory")publicvoidsetMemory(Memorymemory){

this.memory=memory;}

//不用再寫set、get方法}bean.xml配置<beanid="uDisk"class="puter.UDisk"/><beanid="colorPrint"class="puter.ColorPrint"/><beanid="memory"class="puter.Memory"/><beanid="computerBean"class="puter.Computer"><!--不用再配置computerBean中引用的bean<propertyname="usb"ref="uDisk"/><propertyname="print"ref="colorPrint"/><propertyname="memory"ref="memory"/>--></bean>@TestpublicvoidgetComputer(){//模擬計算機組裝測試方法Computercomputer=(Computer)context.getBean("computerBean");computer.showHardWareInfo();}與xml配置文件中配置引用的Bean的區(qū)別是:ComputerBean中不用再配置引用的Bean;這是優(yōu)點;缺點是還是要在spring配置文件中配置uDisk,colorPrint,memory,computerBean這些Bean依賴注入--自動裝配依賴對象對于自動裝配,大家了解一下就可以了,實在不推薦大家使用。例子:<beanid="..."class="..."autowire="byType"/>autowire屬性取值如下:byType:按類型裝配,可以根據(jù)屬性的類型,在容器中尋找跟該類型匹配的bean。如果發(fā)現(xiàn)多個,那么將會拋出異常。如果沒有找到,即屬性值為null。byName:按名稱裝配,可以根據(jù)屬性的名稱,在容器中尋找跟該屬性名相同的bean,如果沒有找到,即屬性值為null。constructor與byType的方式類似,不同之處在于它應(yīng)用于構(gòu)造器參數(shù)。如果在容器中沒有找到與構(gòu)造器參數(shù)類型一致的bean,那么將會拋出異常。autodetect:通過bean類的自省機制(introspection)來決定是使用constructor還是byType方式進行自動裝配。如果發(fā)現(xiàn)默認(rèn)的構(gòu)造器,那么將使用byType方式。通過在classpath自動掃描方式把組件納入spring容器中管理前面的例子我們都是使用XML的bean定義來配置組件。在一個稍大的項目中,通常會有上百個組件,如果這些這組件采用xml的bean定義來配置,顯然會增加配置文件的體積,查找及維護起來也不太方便。spring2.5為我們引入了組件自動掃描機制,他可以在類路徑底下尋找標(biāo)注了@Component、@Service、@Controller、@Repository注解的類,并把這些類納入進spring容器中管理。它的作用和在xml文件中使用bean節(jié)點配置組件是一樣的。要使用自動掃描機制,我們需要打開以下配置信息:<beansxmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"

xmlns:context="/schema/context"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-2.5.xsd

/schema/context/schema/context/spring-context-2.5.xsd"><context:component-scanbase-package=".chongking"/></beans>其中base-package為需要掃描的包(含子包)。@Service用于標(biāo)注業(yè)務(wù)層組件、@Controller用于標(biāo)注控制層組件(如struts中的action)、@Repository用于標(biāo)注數(shù)據(jù)訪問組件,即DAO組件。而@Component泛指組件,當(dāng)組件不好歸類的時候,我們可以使用這個注解進行標(biāo)注。自動掃描式注入Bean(優(yōu)點:配置文件中不用再配置bean)//接口設(shè)計publicinterfaceUSB{//USB接口信息publicvoidinfo(Stringcontent);}publicinterfaceIprint{//打印機接口信息publicvoidinfo(Stringcontent);}@Component("memory")publicclassMemory{//內(nèi)存類publicvoidinfo(Stringconfig){System.out.println("內(nèi)存配置:"+config);}}@Component("computer")publicclassComputer{//面向接口編程,下面的組件都是接口,不是類@Resource(name="usb")privateUSBusb;@Resource(name="colorPrint")privateIprintprint;@Resource(name="memory")privateMemorymemory;publicvoidshowHardWareInfo(){("移動硬盤");("彩色打印機");("金士頓內(nèi)存條");}//上面的注解類也可以寫在set方法上面//不用再寫set、get方法}Spring配置文件配置<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"xmlns:p="/schema/p"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-2.5.xsd/schema/context/schema/context/spring-context-2.5.xsd"><context:component-scanbase-package=".chongking"/></beans>@TestpublicvoidgetComputer(){Computercomputer=(Computer)context.getBean("computer");computer.showHardWareInfo();}@Component(value="usb")publicclassUDiskimplementsUSB{//接口實現(xiàn)類publicvoidinfo(Stringconfig){System.out.println("usb接口配置:"+config);}}@Component("colorPrint")publicclassColorPrintimplementsIprint{publicvoidinfo(Stringconfig){System.out.println("彩色打印機:"+config);}}靜態(tài)代理//接口設(shè)計publicinterfaceAnimal{publicabstractvoideat(Stringfood);publicabstractStringtype();}//AnimalWrapper類是包裝類(代理類)publicclassAnimalWrapper{privateAnimalanimal;publicAnimalWrapper(Animalanimal){this.animal=animal;}publicvoideat(Stringfood){System.out.println("+++Wrapped前置通知!+++");animal.eat(food);System.out.println("+++Wrapped后置通知!+++");}publicStringtype(){System.out.println("WrappedBefore!");Stringtype=animal.type();System.out.println("WrappedAfter!");returntype;}}publicclassMonkeyimplementsAnimal{//接口實現(xiàn)類publicStringtype(){Stringtype="哺乳動物";System.out.println(type);returntype;}publicvoideat(Stringfood){System.out.println("Thefoodis"+food+"!");}}@Testpublicstaticvoidmain(String[]args){AnimalWrapperwrapper=newAnimalWrapper(newMonkey());wrapper.eat("香蕉");}靜態(tài)代理的缺點前面我們通過包裝的模式完成了對Animal所有子類的靜態(tài)代理,在代理方法中,你可以加入一些自己的額外的處理邏輯,就像上面的控制臺輸出語句一樣。那么Spring的前置、后置、環(huán)繞方法通知,通過這種方式可以有限的模擬出來,以Spring的聲明式事務(wù)為例,無非就是在調(diào)用包裝的目標(biāo)方法之前處開啟事務(wù),在之后提交事務(wù),這樣原有的業(yè)務(wù)邏輯沒有受到任何事務(wù)管理代碼的侵入。這種方式的靜態(tài)代理,缺點就是當(dāng)Animal接口中增加了新的方法,那么包裝類中也必須增加這些新的方法。JDK動態(tài)代理publicclassJDKProxyimplements

InvocationHandler{

private

ObjecttargetObject;//要代理的目標(biāo)對象

public

ObjectcreateProxyInstance(ObjecttargetObject){

this.targetObject=targetObject;/**第一個參數(shù)設(shè)置代碼使用的類裝載器,一般采用跟目標(biāo)類相同的類裝載器*第二個參數(shù)設(shè)置代理類實現(xiàn)的接口*第三個參數(shù)設(shè)置回調(diào)對象,當(dāng)代理對象的方法被調(diào)用時,會委派給該參數(shù)指定對象的invoke方法*/

return

Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),

this.targetObject.getClass().getInterfaces(),this); }

//method是被攔截到的方法,args是該方法所需要傳的參數(shù)

public

Objectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{

returnmethod.invoke(this.targetObject,args);//把方法調(diào)用委派給目標(biāo)對象

}}當(dāng)目標(biāo)類實現(xiàn)了接口,我們可以使用jdk的Proxy來生成代理對象。JDK動態(tài)代理案例:/***業(yè)務(wù)接口*@authorAdministrator*/publicinterfaceILogin{

publicbooleanlogin(StringipAddress,Stringname,Stringpassword);}/***目標(biāo)類(接口實現(xiàn)類)*@authorAdministrator**/publicclassLoginImplimplementsILogin{

publicbooleanlogin(StringipAddress,Stringname,Stringpassword){

System.out.println("進入目標(biāo)類的方法");

System.out.println(LoginImpl.class.getName()+"用戶:"+name+"在"+ipAddress+"登錄");

returntrue;}}代理類在后面JDK動態(tài)代理案例(續(xù))-代理類publicclassJDKProxyimplementsInvocationHandler{privateObjecttargetObject;//要代理的目標(biāo)對象publicObjectcreateProxyInstance(ObjecttargetObject){//創(chuàng)建代理對象this.targetObject=targetObject;//賦值,下面invoke方法用到這個對象/**參數(shù)1:設(shè)置代碼使用的類裝載器,一般采用跟目標(biāo)類相同的類裝載器*參數(shù)2:設(shè)置代理類實現(xiàn)的接口*參數(shù)3:設(shè)置回調(diào)對象,當(dāng)代理對象的方法被調(diào)用時(這里對應(yīng)的是LoginImpl類中的login方法),會委派給該參數(shù)指定對象的invoke方法*/ObjectproxyInstance=Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this);returnproxyInstance;}//通知的概念就是要實現(xiàn)某個功能(這個方法就是環(huán)繞通知:

溫馨提示

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

最新文檔

評論

0/150

提交評論