




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
Spring企業(yè)開發(fā)
Spring是什么Spring是一個(gè)開源的控制反轉(zhuǎn)(InversionofControl,IoC)和面向切面(AOP)的容器框架.它的主要目的是簡(jiǎn)化企業(yè)開發(fā).IOC控制反轉(zhuǎn)publicclassPersonService{//服務(wù)層
privatePersonDaopersonDao=new
PersonDaoBean();
publicvoidsave(Personperson){//保存一個(gè)對(duì)象personDao.save(person);}}PersonDaoBean是在應(yīng)用內(nèi)部創(chuàng)建及維護(hù)的(在PersonService類中new出來(lái)的)。所謂控制反轉(zhuǎn)就是應(yīng)用本身不負(fù)責(zé)依賴對(duì)象的創(chuàng)建及維護(hù),依賴對(duì)象的創(chuàng)建及維護(hù)是由外部容器負(fù)責(zé)的。這樣控制權(quán)就由應(yīng)用轉(zhuǎn)移到了外部容器,控制權(quán)的轉(zhuǎn)移就是所謂反轉(zhuǎn)。依賴注入(DependencyInjection)當(dāng)我們把依賴對(duì)象交給外部容器負(fù)責(zé)創(chuàng)建,那么PersonService類可以改成如下:publicclassPersonService{
privatePersonDaopersonDao;
//通過(guò)構(gòu)造器參數(shù),讓容器把創(chuàng)建好的依賴對(duì)象注入進(jìn)PersonService,當(dāng)然也可以使用setter方法進(jìn)行注入。
publicPersonService(PersonDaopersonDao){this.personDao=personDao;}
publicvoidsave(Personperson){personDao.save(person);}}所謂依賴注入就是指:在運(yùn)行期,由外部容器動(dòng)態(tài)地將依賴對(duì)象注入到組件中。為何要使用Spring在項(xiàng)目中引入spring立即可以帶來(lái)下面的好處降低組件之間的耦合度,實(shí)現(xiàn)軟件各層之間的解耦。
可以使用容器提供的眾多服務(wù),如:事務(wù)管理服務(wù)、消息服務(wù)等等。當(dāng)我們使用容器管理事務(wù)時(shí),開發(fā)人員就不再需要手工控制事務(wù).也不需處理復(fù)雜的事務(wù)傳播。容器提供單例模式支持,開發(fā)人員不再需要自己編寫實(shí)現(xiàn)代碼。容器提供了AOP技術(shù),利用它很容易實(shí)現(xiàn)如權(quán)限攔截、運(yùn)行期監(jiān)控等功能。容器提供的眾多輔作類,使用這些類能夠加快應(yīng)用的開發(fā),如:JdbcTemplate、HibernateTemplate。Spring對(duì)于主流的應(yīng)用框架提供了集成支持,如:集成Hibernate、JPA、Struts等,這樣更便于應(yīng)用的開發(fā)。ControllerServiceDAO使用Spring的好處當(dāng)使用spring時(shí),我們可以使用容器提供的眾多服務(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,針對(duì)下面這兩種業(yè)務(wù)需求,我們?cè)撊绾巫???種可能的業(yè)務(wù)需求:要求Bean1.update()和Bean2.save()在同一個(gè)事務(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,我們只需要通過(guò)聲明式的事務(wù)屬性配置就可以輕松地實(shí)現(xiàn)這兩種業(yè)務(wù)需求1.要求Bean1.update()和Bean2.save()的在同一個(gè)事務(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í)與重量級(jí)概念的劃分經(jīng)常會(huì)有同學(xué)問(wèn)到spring屬于輕量級(jí)框架,還是重量框架?其實(shí)劃分一個(gè)應(yīng)用是否屬于輕量級(jí)還是重量級(jí),主要看它使用了多少服務(wù).使用的服務(wù)越多,容器要為普通java對(duì)象做的工作就越多,必然會(huì)影響到應(yīng)用的發(fā)布時(shí)間或者是運(yùn)行性能.對(duì)于spring容器,它提供了很多服務(wù),但這些服務(wù)并不是默認(rèn)為應(yīng)用打開的,應(yīng)用需要某種服務(wù),還需要指明使用該服務(wù),如果應(yīng)用使用的服務(wù)很少,如:只使用了spring核心服務(wù),那么我們可以認(rèn)為此時(shí)應(yīng)用屬于輕量級(jí)的,如果應(yīng)用使用了spring提供的大部分服務(wù),這時(shí)應(yīng)用就屬于重量級(jí)。目前EJB容器就因?yàn)樗J(rèn)為應(yīng)用提供了EJB規(guī)范中所有的功能,所以它屬于重量級(jí)。使用Spring需要的jar到/download下載spring,然后進(jìn)行解壓縮,在解壓目錄中找到下面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工程(其實(shí)普通j2se工程也可以)使用myeclipse添加Spring應(yīng)用第二步:在web工程中添加Spring框架支持使用myeclipse添加Spring應(yīng)用這里只是簡(jiǎn)單應(yīng)用,沒(méi)有涉及到和其它框架的集成,因此選擇前面兩個(gè)就可以了。使用myeclipse添加Spring應(yīng)用這步的目的是生成Spring配置文件applicationContext.xml文件位置是src使用myeclipse添加Spring應(yīng)用框架添加完成之后的效果使用myeclipse添加Spring應(yīng)用publicclassUserInfo{privateIntegerid;privateStringname;privateStringaddress;privateIntegerage;//setandgetmethod……}第三步:創(chuàng)建一個(gè)實(shí)體類;并生成屬性對(duì)應(yīng)的set/get方法使用myeclipse添加Spring應(yīng)用第四步:根據(jù)左邊的實(shí)體類屬性名稱和數(shù)據(jù)類型在Spring配置文件中配置一個(gè)bean;這個(gè)bean的id值是userInfoBean這個(gè)id屬性名稱對(duì)應(yīng)的值在applicationContext.xml必須是唯一;不能存在同名;在應(yīng)用程序中將根據(jù)id名稱來(lái)獲取這個(gè)bean使用myeclipse添加Spring應(yīng)用//編寫測(cè)試類,從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());}}第五步:編寫測(cè)試類;從spring容器中根據(jù)bean的id獲取bean對(duì)象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)其它的配置和測(cè)試跟使用myeclipse是一樣的。在java體系中絕大部分的框架應(yīng)用所涉及到的引用基本上都是jar文件和配置文件。Jar文件和配置文件有多種渠道可以獲取;可以從官方網(wǎng)站上下載;可以使用別人現(xiàn)有的;可以通過(guò)其它渠道獲取。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的參考手冊(cè)或spring的例子中得到。配置文件的取名可以任意,文件可以存放在任何目錄下,但考慮到通用性,一般放在類路徑下。編寫spring配置文件時(shí),不能出現(xiàn)幫助信息由于spring的schema文件位于網(wǎng)絡(luò)上,如果機(jī)器不能連接到網(wǎng)絡(luò),那么在編寫配置信息時(shí)候就無(wú)法出現(xiàn)提示信息,解決方法有兩種:1。讓機(jī)器上網(wǎng),eclipse會(huì)自動(dòng)從網(wǎng)絡(luò)上下載schema文件并緩存在硬盤上。2。手動(dòng)添加schema文件,方法如下:windwos->preferences->myeclipse->filesandeditors->xml->xmlcatalog點(diǎn)"add",在出現(xiàn)的窗口中的KeyType中選擇URI,在location中選"Filesystem",然后在spring解壓目錄的dist/resources目錄中選擇spring-beans-2.5.xsd,回到設(shè)置窗口的時(shí)候不要急著關(guān)閉窗口,應(yīng)把窗口中的KeyType改為Schemalocation,Key改為/schema/beans/spring-beans-2.5.xsd實(shí)例化spring容器實(shí)例化Spring容器常用的兩種方式:方法一:在類路徑下尋找配置文件來(lái)實(shí)例化容器ApplicationContextctx=newClassPathXmlApplicationContext(newString[]{"beans.xml"});方法二:在文件系統(tǒng)路徑下尋找配置文件來(lái)實(shí)例化容器ApplicationContextctx=newFileSystemXmlApplicationContext(newString[]{“d:\\beans.xml“});Spring的配置文件可以指定多個(gè),可以通過(guò)String數(shù)組傳入。從spring容器中得到bean當(dāng)spring容器啟動(dòng)后,因?yàn)閟pring容器可以管理bean對(duì)象的創(chuàng)建,銷毀等生命周期,所以我們只需從容器直接獲取Bean對(duì)象就行,而不用編寫一句代碼來(lái)創(chuàng)建bean對(duì)象。從容器獲取bean對(duì)象的代碼如下: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é)點(diǎn)
for(Elementelement:beans){Stringid=element.attributeValue("id");//獲取id屬性值
Stringclazz=element.attributeValue("class");//獲取class屬性值
BeanDefinitionbeanDefine=newBeanDefinition(id,clazz);beanDefines.add(beanDefine);}}catch(Exceptione){e.printStackTrace();}}}三種實(shí)例化bean的方式-使用類構(gòu)造器實(shí)例化//實(shí)體類設(shè)計(jì)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測(cè)試代碼publicvoidgetUserInfo(){ UserInfouserInfo= (UserInfo)context.getBean("normalBean"); System.out.println(userInfo.getId()+": "+userInfo.getName()+":"+userInfo.getAddress());}三種實(shí)例化bean的方式-使用靜態(tài)工廠方法實(shí)例化//工廠類設(shè)計(jì)publicclassBeanFactory{publicstaticUserInfofactoryDao(){returnnewUserInfo(1,"王五","南寧",21);}}applicationContext.xml配置<beanid="staticFactoryBean" class=".chongking.BeanFactory"
factory-method="factoryDao"/>publicvoidstaticFactoryBean(){//測(cè)試代碼 UserInfouserInfo=(UserInfo)context.getBean("staticFactoryBean"); System.out.println(userInfo.getId()+": "+userInfo.getName()+":"+userInfo.getAddress());}//實(shí)體類設(shè)計(jì)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…}三種實(shí)例化bean的方式-使用實(shí)例工廠方法實(shí)例化//工廠類設(shè)計(jì)publicclassBeanFactory{publicUserInfocreateUserInfo(){returnnewUserInfo(1,"王五","南寧",21);}}applicationContext.xml配置<beanid="factoryBean"class=".chongking.BeanFactory"/><beanid="instanceFactoryBean"factory-bean="factoryBean"factory-method="createUserInfo"/>//使用實(shí)例工廠方法實(shí)例化測(cè)試publicvoidinstanceFactoryBean(){UserInfouserInfo=(UserInfo)context.getBean("instanceFactoryBean");System.out.println(userInfo.getId()+":"+userInfo.getName()+":"+userInfo.getAddress());}Bean的作用域(scope屬性).singleton
在每個(gè)SpringIoC容器中一個(gè)bean定義只有一個(gè)對(duì)象實(shí)例。默認(rèn)情況下會(huì)在容器啟動(dòng)時(shí)初始化bean,但我們可以指定Bean節(jié)點(diǎn)的lazy-init=“true”來(lái)延遲初始化bean,這時(shí)候,只有第一次獲取bean會(huì)才初始化bean。如:
<beanid="xxx"class=".chongking.OrderServiceBean"lazy-init="true"/>如果想對(duì)所有bean都應(yīng)用延遲初始化,可以在根節(jié)點(diǎn)beans設(shè)置default-lazy-init=“true“,如下:<beansdefault-lazy-init="true“...>可以通過(guò)在構(gòu)造函數(shù)中輸出信息來(lái)跟蹤.prototype
每次從容器獲取bean都是新的對(duì)象。.request.session.globalsessionrequest,session,globalsession是針對(duì)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容器對(duì)象(注意:不是ApplicationContext)@Beforepublicvoidbefore(){System.out.println("before...");context=newClassPathXmlApplicationContext("applicationContext.xml");}@TestpublicvoidgetEmployeeBean(){
//Employee類中有兩個(gè)方法:init();和close()Employeeemployee=(Employee)context.getBean("empBean");System.out.println(employee.getName());}@Afterpublicvoidafter(){
context.close();//需要顯示調(diào)用}}注入依賴對(duì)象-基本類型對(duì)象注入<beanid="empBean"class=".chongking.Employee"><propertyname="id"value="1"/><propertyname="name"value="李四"/><propertyname="address"value="柳州"/></bean>publicclassEmployee{//實(shí)體類設(shè)計(jì)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注入依賴對(duì)象-構(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>實(shí)體類構(gòu)造方法publicEmployee(Integer
id,String
name,String
address){System.out.println("帶參數(shù)構(gòu)造函數(shù)");this.id=id;=name;this.address=address;}@TestpublicvoidgetEmployeeBean(){//測(cè)試方法Employeeemployee=(Employee)context.getBean("empBean");System.out.println(employee.getId()+":"+employee.getName()+":"+employee.getAddress());}注入依賴對(duì)象-注入其它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(){//測(cè)試類
Computercomputer=
(Computer)context.getBean("computerBean");
computer.testCput();}publicclassComputer{privateCpucpu;//set方法是必須的(set注入)publicvoidsetCpu(Cpucpu){this.cpu=cpu;}publicCpugetCpu(){returncpu;}publicvoidtestCput(){cpu.hardwareInfo();}}注入依賴對(duì)象-注入其它Bean-2applicationContext.xml配置<beanid="computerBean"class=".chongking.Computer"><propertyname="cpu"><beanclass=".chongking.Cpu"/></property></bean>publicclassCpu{publicvoidhardwareInfo(){System.out.println("AMD速龍");}}@TestpublicvoidgetComputer(){//測(cè)試類
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í)-通過(guò)Bean注入模擬計(jì)算機(jī)組裝//接口設(shè)計(jì)publicinterfaceUSB{//USB接口信息publicvoidinfo(Stringcontent);}publicinterfaceIprint{//打印機(jī)接口信息publicvoidinfo(Stringcontent);}publicclassMemory{//內(nèi)存類publicvoidinfo(Stringconfig){System.out.println("內(nèi)存配置:"+config);}}publicclassComputer{//計(jì)算機(jī)類privateUSBusb;privateIprintprint;privateMemorymemory;publicvoidshowHardWareInfo(){("移動(dòng)硬盤");("彩色打印機(jī)");("金士頓內(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(){//模擬計(jì)算機(jī)組裝測(cè)試方法Computercomputer=(Computer)context.getBean("computerBean");computer.showHardWareInfo();}//接口實(shí)現(xiàn)類publicclassUDiskimplementsUSB{publicvoidinfo(Stringconfig){System.out.println("usb接口配置:"+config);}}publicclassColorPrintimplementsIprint{publicvoidinfo(Stringconfig){System.out.println("彩色打印機(jī):"+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(){//測(cè)試類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注入(用于注解方式)注入依賴對(duì)象可以采用手工裝配或自動(dòng)裝配,在實(shí)際應(yīng)用中建議使用手工裝配,因?yàn)樽詣?dòng)裝配會(huì)產(chǎn)生未知情況,開發(fā)人員無(wú)法預(yù)見最終的裝配結(jié)果。1.手工裝配依賴對(duì)象2.自動(dòng)裝配依賴對(duì)象依賴注入--手工裝配手工裝配依賴對(duì)象,在這種方式中又有兩種編程方式1.在xml配置文件中,通過(guò)在bean節(jié)點(diǎn)下配置,如<beanid="orderService"class=".chongking.People"><constructor-argindex=“0”type=“java.lang.Integer”value=“1”/>//構(gòu)造器注入(帶參構(gòu)造函數(shù)第1個(gè)值)
<constructor-argindex=“1”type=“java.lang.String”value=“李四”/>//構(gòu)造器注入(帶參構(gòu)造函數(shù)第2個(gè)值)<constructor-argindex=“2”type=“java.lang.String”value=“柳州”/>//構(gòu)造器注入(帶參構(gòu)造函數(shù)第3個(gè)值)
<propertyname=“name”value=“李四”/>//屬性setter方法注入</bean>2.在java代碼中使用@Autowired或@Resource注解方式進(jìn)行裝配。但我們需要在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>這個(gè)配置隱式注冊(cè)了多個(gè)對(duì)注釋進(jìn)行解析處理的處理器:AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor注:@Resource注解在spring安裝目錄的lib\j2ee\common-annotations.jar依賴注入--手工裝配在java代碼中使用@Autowired或@Resource注解方式進(jìn)行裝配,這兩個(gè)注解的區(qū)別是:@Autowired默認(rèn)按類型裝配,@Resource默認(rèn)按名稱裝配,當(dāng)找不到與名稱匹配的bean才會(huì)按類型裝配。
@AutowiredprivatePersonDaopersonDao;//用于字段上@AutowiredpublicvoidsetOrderDao(OrderDaoorderDao){//用于屬性的setter方法上this.orderDao=orderDao;}@Autowired注解是按類型裝配依賴對(duì)象,默認(rèn)情況下它要求依賴對(duì)象必須存在,如果允許null值,可以設(shè)置它required屬性為false@Autowired(required=false)。如果我們想使用按名稱裝配,可以結(jié)合@Qualifier注解一起使用。如下:@Autowired@Qualifier("personDaoBean")privatePersonDaopersonDao;@Resource注解和@Autowired一樣,也可以標(biāo)注在字段或?qū)傩缘膕etter方法上,但它默認(rèn)按名稱裝配。名稱可以通過(guò)@Resource的name屬性指定,如果沒(méi)有指定name屬性,當(dāng)注解標(biāo)注在字段上,即默認(rèn)取字段的名稱作為bean名稱尋找依賴對(duì)象,當(dāng)注解標(biāo)注在屬性的setter方法上,即默認(rèn)取屬性名作為bean名稱尋找依賴對(duì)象。
@Resource(name=“personDaoBean”)privatePersonDaopersonDao;//用于字段上注意:如果沒(méi)有指定name屬性,并且按照默認(rèn)的名稱仍然找不到依賴對(duì)象時(shí),@Resource注解會(huì)回退到按類型裝配。但一旦指定了name屬性,就只能按名稱裝配了。依賴注入--手工裝配-注解裝配AutowiredpublicclassComputer{//計(jì)算機(jī)類
@AutowiredprivateUSBusb;
@AutowiredprivateIprintprint;
@AutowiredprivateMemorymemory;publicvoidshowHardWareInfo(){("移動(dòng)硬盤");("彩色打印機(jī)");("金士頓內(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(){//模擬計(jì)算機(jī)組裝測(cè)試方法Computercomputer=(Computer)context.getBean("computerBean");computer.showHardWareInfo();}與xml配置文件中配置引用的Bean的區(qū)別是:ComputerBean中不用再配置引用的Bean;這是優(yōu)點(diǎn);缺點(diǎn)是還是要在spring配置文件中配置uDisk,colorPrint,memory,computerBean這些Bean依賴注入--手工裝配-注解裝配ResourcepublicclassComputer{privateUSBusb;privateIprintprint;privateMemorymemory;publicvoidshowHardWareInfo(){
("移動(dòng)硬盤");
("彩色打印機(jī)");
("金士頓內(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(){//模擬計(jì)算機(jī)組裝測(cè)試方法Computercomputer=(Computer)context.getBean("computerBean");computer.showHardWareInfo();}與xml配置文件中配置引用的Bean的區(qū)別是:ComputerBean中不用再配置引用的Bean;這是優(yōu)點(diǎn);缺點(diǎn)是還是要在spring配置文件中配置uDisk,colorPrint,memory,computerBean這些Bean依賴注入--自動(dòng)裝配依賴對(duì)象對(duì)于自動(dòng)裝配,大家了解一下就可以了,實(shí)在不推薦大家使用。例子:<beanid="..."class="..."autowire="byType"/>autowire屬性取值如下:byType:按類型裝配,可以根據(jù)屬性的類型,在容器中尋找跟該類型匹配的bean。如果發(fā)現(xiàn)多個(gè),那么將會(huì)拋出異常。如果沒(méi)有找到,即屬性值為null。byName:按名稱裝配,可以根據(jù)屬性的名稱,在容器中尋找跟該屬性名相同的bean,如果沒(méi)有找到,即屬性值為null。constructor與byType的方式類似,不同之處在于它應(yīng)用于構(gòu)造器參數(shù)。如果在容器中沒(méi)有找到與構(gòu)造器參數(shù)類型一致的bean,那么將會(huì)拋出異常。autodetect:通過(guò)bean類的自省機(jī)制(introspection)來(lái)決定是使用constructor還是byType方式進(jìn)行自動(dòng)裝配。如果發(fā)現(xiàn)默認(rèn)的構(gòu)造器,那么將使用byType方式。通過(guò)在classpath自動(dòng)掃描方式把組件納入spring容器中管理前面的例子我們都是使用XML的bean定義來(lái)配置組件。在一個(gè)稍大的項(xiàng)目中,通常會(huì)有上百個(gè)組件,如果這些這組件采用xml的bean定義來(lái)配置,顯然會(huì)增加配置文件的體積,查找及維護(hù)起來(lái)也不太方便。spring2.5為我們引入了組件自動(dòng)掃描機(jī)制,他可以在類路徑底下尋找標(biāo)注了@Component、@Service、@Controller、@Repository注解的類,并把這些類納入進(jìn)spring容器中管理。它的作用和在xml文件中使用bean節(jié)點(diǎn)配置組件是一樣的。要使用自動(dòng)掃描機(jī)制,我們需要打開以下配置信息:<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ù)訪問(wèn)組件,即DAO組件。而@Component泛指組件,當(dāng)組件不好歸類的時(shí)候,我們可以使用這個(gè)注解進(jìn)行標(biāo)注。自動(dòng)掃描式注入Bean(優(yōu)點(diǎn):配置文件中不用再配置bean)//接口設(shè)計(jì)publicinterfaceUSB{//USB接口信息publicvoidinfo(Stringcontent);}publicinterfaceIprint{//打印機(jī)接口信息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(){("移動(dòng)硬盤");("彩色打印機(jī)");("金士頓內(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{//接口實(shí)現(xiàn)類publicvoidinfo(Stringconfig){System.out.println("usb接口配置:"+config);}}@Component("colorPrint")publicclassColorPrintimplementsIprint{publicvoidinfo(Stringconfig){System.out.println("彩色打印機(jī):"+config);}}靜態(tài)代理//接口設(shè)計(jì)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{//接口實(shí)現(xiàn)類publicStringtype(){Stringtype="哺乳動(dòng)物";System.out.println(type);returntype;}publicvoideat(Stringfood){System.out.println("Thefoodis"+food+"!");}}@Testpublicstaticvoidmain(String[]args){AnimalWrapperwrapper=newAnimalWrapper(newMonkey());wrapper.eat("香蕉");}靜態(tài)代理的缺點(diǎn)前面我們通過(guò)包裝的模式完成了對(duì)Animal所有子類的靜態(tài)代理,在代理方法中,你可以加入一些自己的額外的處理邏輯,就像上面的控制臺(tái)輸出語(yǔ)句一樣。那么Spring的前置、后置、環(huán)繞方法通知,通過(guò)這種方式可以有限的模擬出來(lái),以Spring的聲明式事務(wù)為例,無(wú)非就是在調(diào)用包裝的目標(biāo)方法之前處開啟事務(wù),在之后提交事務(wù),這樣原有的業(yè)務(wù)邏輯沒(méi)有受到任何事務(wù)管理代碼的侵入。這種方式的靜態(tài)代理,缺點(diǎn)就是當(dāng)Animal接口中增加了新的方法,那么包裝類中也必須增加這些新的方法。JDK動(dòng)態(tài)代理publicclassJDKProxyimplements
InvocationHandler{
private
ObjecttargetObject;//要代理的目標(biāo)對(duì)象
public
ObjectcreateProxyInstance(ObjecttargetObject){
this.targetObject=targetObject;/**第一個(gè)參數(shù)設(shè)置代碼使用的類裝載器,一般采用跟目標(biāo)類相同的類裝載器*第二個(gè)參數(shù)設(shè)置代理類實(shí)現(xiàn)的接口*第三個(gè)參數(shù)設(shè)置回調(diào)對(duì)象,當(dāng)代理對(duì)象的方法被調(diào)用時(shí),會(huì)委派給該參數(shù)指定對(duì)象的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)對(duì)象
}}當(dāng)目標(biāo)類實(shí)現(xiàn)了接口,我們可以使用jdk的Proxy來(lái)生成代理對(duì)象。JDK動(dòng)態(tài)代理案例:/***業(yè)務(wù)接口*@authorAdministrator*/publicinterfaceILogin{
publicbooleanlogin(StringipAddress,Stringname,Stringpassword);}/***目標(biāo)類(接口實(shí)現(xiàn)類)*@authorAdministrator**/publicclassLoginImplimplementsILogin{
publicbooleanlogin(StringipAddress,Stringname,Stringpassword){
System.out.println("進(jìn)入目標(biāo)類的方法");
System.out.println(LoginImpl.class.getName()+"用戶:"+name+"在"+ipAddress+"登錄");
returntrue;}}代理類在后面JDK動(dòng)態(tài)代理案例(續(xù))-代理類publicclassJDKProxyimplementsInvocationHandler{privateObjecttargetObject;//要代理的目標(biāo)對(duì)象publicObjectcreateProxyInstance(ObjecttargetObject){//創(chuàng)建代理對(duì)象this.targetObject=targetObject;//賦值,下面invoke方法用到這個(gè)對(duì)象/**參數(shù)1:設(shè)置代碼使用的類裝載器,一般采用跟目標(biāo)類相同的類裝載器*參數(shù)2:設(shè)置代理類實(shí)現(xiàn)的接口*參數(shù)3:設(shè)置回調(diào)對(duì)象,當(dāng)代理對(duì)象的方法被調(diào)用時(shí)(這里對(duì)應(yīng)的是LoginImpl類中的login方法),會(huì)委派給該參數(shù)指定對(duì)象的invoke方法*/ObjectproxyInstance=Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this);returnproxyInstance;}//通知的概念就是要實(shí)現(xiàn)某個(gè)功能(這個(gè)方法就是環(huán)繞通知:
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 寵物健康護(hù)理員考試考試題庫(kù)一
- 安全生產(chǎn)一級(jí)交底
- 2025至2030年中國(guó)氣熱春卷機(jī)市場(chǎng)分析及競(jìng)爭(zhēng)策略研究報(bào)告
- 2025至2030年中國(guó)正方形禮品盒市場(chǎng)調(diào)查研究報(bào)告
- 2025至2030年中國(guó)橡膠修補(bǔ)劑行業(yè)發(fā)展研究報(bào)告
- 2025至2030年中國(guó)模具式貨架行業(yè)發(fā)展研究報(bào)告
- 2025至2030年中國(guó)棱鏡式反光膜行業(yè)投資前景及策略咨詢報(bào)告
- 2025至2030年中國(guó)梅花式落線機(jī)市場(chǎng)調(diào)查研究報(bào)告
- 2025至2030年中國(guó)標(biāo)準(zhǔn)發(fā)票專用印章市場(chǎng)調(diào)查研究報(bào)告
- 2025至2030年中國(guó)楓木色主副辦公臺(tái)市場(chǎng)分析及競(jìng)爭(zhēng)策略研究報(bào)告
- DL-T-1878-2018燃煤電廠儲(chǔ)煤場(chǎng)盤點(diǎn)導(dǎo)則
- 供應(yīng)商產(chǎn)品及過(guò)程變更控制程序
- 《2022年上海市初中語(yǔ)文課程終結(jié)性評(píng)價(jià)指南》中規(guī)定的150個(gè)文言實(shí)詞
- 《鐵道概論鐵路車站》PPT課件
- T∕CNTAC 22-2018 絨毛織物掉毛性的試驗(yàn)方法
- TI-BQ40Z50-軟件(課堂PPT)
- 建設(shè)項(xiàng)目3000萬(wàn)元以下估算投資額分檔收費(fèi)標(biāo)準(zhǔn)
- 《禮儀培訓(xùn)》PPT課件
- 歷代皇帝年號(hào)表
- 超星爾雅學(xué)習(xí)通《時(shí)間管理》章節(jié)測(cè)試含答案
- 110ZM241塔型圖
評(píng)論
0/150
提交評(píng)論