标题: JAVA编程:Introducing to Spring Framework [打印本页] 作者: 山那边是海 时间: 2015-1-18 11:52 标题: JAVA编程:Introducing to Spring Framework 再举这样一个例子:如果你想对一个数字取绝对值,你会怎么做呢?java的做法是intc=Math.abs(-166);而ruby的做法是:c=-166.abs。呵呵,这就看出了java与ruby的区别。IntroducingtoSpringFrameworkRodJohnson译者:yanger,taowen校正:taowen关于SpringFramework,往年炎天你大概已闻声良多的群情。在本文中,我将试图注释Spring能完成甚么,和我怎样会以为它能匡助你开辟J2EE使用程序。又来一个framework?你大概正在想“不外是别的一个的framework”。当已有很多开放源代码(和专有)J2EEframework时,为何你还要耐下心子读这篇文章或往下载SpringFramework?我信任Spring是共同的,有几个缘故原由:它存眷的范畴是其他很多盛行的Framework不曾存眷的。Spring要供应的是一种办理你的营业对象的办法。Spring既是周全的又是模块化的。Spring有分层的系统布局,这意味着你能选择仅仅利用它任何一个自力的部分,而它的架构又是外部分歧。因而你能从你的进修中,失掉最年夜的代价。比方,你大概选择仅仅利用Spring来复杂化JDBC的利用,或用来办理一切的营业对象。它的计划从一入手下手就是要匡助你编写易于测试的代码。Spring是利用测试驱动开辟的工程的幻想框架。Spring不会给你的工程增加对其他的框架依附。Spring大概称得上是个一站式办理计划,供应了一个典范使用所必要的年夜部分基本架构。它还触及到了其他framework没有思索到的内容。只管它仅仅是一个从2003年2月才入手下手的开源项目,但Spring有深挚的汗青基本。这个开源工程是劈头自我在2002年晚些时分出书的《ExpertOne-on-OneJ2EE计划与开辟》书中的基本性代码。这本书展现了Spring面前的基本性架构想想。但是,对这个基本架构的观点能够追溯到2000年的早些时分,而且反应了我为一系列贸易工程开辟基本布局的乐成履历。2003年1月,Spring已落户于SourceForge上了。如今有10个开辟职员,个中6个是高度投进的主动份子。Spring架构上的优点在我们进进细节之前,让我们来看看Spring可以给工程带来的各种优点:Spring能无效地构造你的两头层对象,不论你是不是选择利用了EJB。假如你仅仅利用了Struts或其他为J2EE的API特制的framework,Spring努力于办理剩下的成绩。Spring能打消在很多工程中罕见的对Singleton的过量利用。依据我的履历,这是一个很年夜的成绩,它下降了体系的可测试性和面向对象的水平。经由过程一种在分歧使用程序和项目间分歧的办法来处置设置文件,Spring能打消林林总总自界说格局的属性文件的必要。已经对某个类要寻觅的是哪一个邪术般的属性项或体系属性感应不解,为此不能不往读Javadoc乃至源编码?有了Spring,你仅仅必要看看类的JavaBean属性。InversionofControl的利用(鄙人面会商)匡助完成了这类简化。经由过程把对接口编程而不是对类编程的价值几近削减到没有,Spring可以增进养成好的编程习气。Spring被计划为让利用它创立的使用尽量少的依附于他的APIs。在Spring使用中的年夜多半营业对象没有依附于Spring。利用Spring构建的使用程序易于单位测试。Spring能使EJB的利用成为一个完成选择,而不是使用架构的一定选择。你能选择用POJOs或localEJBs来完成营业接口,却不会影响挪用代码。Spring匡助你办理很多成绩而无需利用EJB。Spring能供应一种EJB的交换物,它们合用于很多web使用。比方,Spring能利用AOP供应声明性事件办理而欠亨过EJB容器,假如你仅仅必要与单个数据库打交道,乃至不必要一个JTA完成。Spring为数据存取供应了一个分歧的框架,不管是利用的是JDBC仍是O/Rmapping产物(如Hibernate)。Spring的确使你能经由过程最复杂可行的办理举措来办理你的成绩。而这是有有很年夜代价的。Spring做了些甚么?Spring供应很多功效,在此我将顺次疾速地展现其各个次要方面。义务形貌起首,让我们明白Spring局限。只管Spring掩盖了很多方面,但我们对它应当涉甚么,甚么不该该触及有分明的熟悉。Spring的次要目标是使J2EE易用和增进好编程习气。Spring不从头轮子。因而,你发明在Spring中没有logging,没有毗连池,没有散布式事件调剂。一切这些工具均有开源项目供应(比方我们用于处置一切日记输入的CommonsLogging和CommonsDBCP),或由你的使用程序服务器供应了。出于一样的的缘故原由,我们没有供应O/Rmapping层。关于这个成绩已有了像Hibernate和JDO如许的优异办理计划。Spring的方针就是让已有的手艺加倍易用。比方,只管我们没有底层事件和谐处置,但我们供应了一个笼统层掩盖了JTA或任何其他的事件战略。Spring没有间接和其他的开源项目合作,除非我们感应我们能供应新的一些工具。比方,象很多开辟职员一样,我们历来没有对Struts感应乐意过,而且以为到在MVCwebframework中另有改善的余地。在某些范畴,比方轻量级的IoC容器和AOP框架,Spring的确有间接的合作,可是在这些范畴还没有已较为盛行的办理计划。(Spring在这些范畴是开路前锋。)Spring也得益于内涵的分歧性。一切的开辟者都在唱一样的的赞歌,基本设法仍然与ExpertOne-on-OneJ2EE计划与开辟中提出的差未几。而且我们已可以在多个范畴中利用一些中央的观点,比方InversionofControl。Spring在使用服务器之间是可移植的。固然包管可移植性老是一种应战,可是我们制止利用任何平台特有或非尺度的工具,而且撑持在WebLogic,Tomcat,Resin,JBoss,WebSphere和其他的使用服务器上的用户。InversionofControl容器Spring计划的中心是org.springframework.beans包,它是为与JavaBeans一同事情而计划的。这个包一样平常不间接被用户利用,而是作为很多其他功效的基本。下一个层面高一些的笼统是"BeanFactory"。一个Springbeanfactory是一个通用的Factory,它使对象可以按称号猎取,而且能办理对象之间的干系。Beanfactories撑持两种形式的对象:Singleton:在此形式中,有一个具有特命名称的共享对象实例,它在查找时被猎取。这是默许的,并且是最为常常利用的。它关于无形态对象是一种幻想的形式。Prototype:在此形式中,每次猎取将创立一个自力的对象。比方,这能够被用于让用户具有他们本人的对象。因为org.springframwork.beans.factory.BeanFactory是一个复杂的接口,它能被大批底层存储办法完成。你可以便利地完成你本人的BeanFactory,只管很罕用户必要这么做。最为经常使用的BeanFactory界说是:XmlBeanFactory:可剖析复杂直不雅的界说类和定名对象属性的XML布局。我们供应了一个DTD来使编写更简单。ListableBeanFactoryImpl:供应懂得析寄存在属性文件中的bean界说的才能,而且可经由过程编程创立BeanFactories。每一个bean界说多是一个POJO(经由过程类名和JavaBean初始属性界说),或是一个FactoryBean。FactoryBean接口增加了一个直接层。一般,这用于创立利用AOP或其他办法的代办署理对象:比方,增加声明性事件办理的代办署理。(这在观点上和EJB的interception类似,但完成得更复杂。)BeanFactories能在一个条理布局当选择性地介入,承继ancestor(先人)的界说。这使得在全部使用中大众设置的共享成为大概,固然一般资本,如controllerservlets,还具有他们本人的自力的对象汇合。这类利用JavaBeans的念头在《ExpertOne-on-OneJ2EEDesignandDevelopment》的第四章中有形貌,在TheServerSide网站上的有收费的PDF版本(http://www.theserverside.com/resources/article.jsp?l=RodJohnsonInterview)。经由过程BeanFactory观点,Spring成为一个InversionofControl的容器。(我不怎样喜好container这个词,由于它令人遐想到分量级容器,如EJB容器。Spring的BeanFactory是一个可经由过程一行代码创立的容器,而且不必要特别的部署步骤。)InversionofControl面前的观点常常表述为Hollywood准绳的:“Don’tcallme,I’llcallyou。”IoC将把持创立的职责搬进了框架中,并把它从使用代码离开开来。触及到设置的中央,意义是说在传统的容器系统布局中,如EJB,一个组件能够挪用容器并问“我必要它给我唱工作的对象X在那里?”;利用IoC容器则只需指出组件必要X对象,在运转时容器会供应给它。容器是经由过程检察办法的参数表(比方JavaBean的属性)做到的,也大概依据设置数据如XML。IoC有几个主要的优点,比方:由于组件不必要在运转工夫寻觅互助者,以是他们能够更复杂的编写和保护。在Spring版的IoC里,组件经由过程表露JavaBean的setter办法表达他们依附的其他组件。这相称于EJB经由过程JNDI来查找,EJB查找必要开辟职员编写代码。一样缘故原由,使用代码更简单测试。JavaBean属性是复杂的,属于Java中心的,而且是简单测试的:仅编写一个自包括的Junit测试办法用来创立对象和设置相干属性便可。一个好的IoC完成保存了强范例。假如你必要利用一个通用的factory来寻觅互助者,你必需经由过程范例转换将前往了局变化为想要的范例。这不是一个年夜不了的成绩,可是不雅。利用IoC,你在你的代码中表达了强范例依附,框架将卖力范例转换。这意味着在框架设置使用时,范例不婚配将招致毛病;在你的代码中,你无需忧虑范例转换非常。年夜部分营业对象不依附于IoC容器的APIs。这使得很简单利用遗留上去的代码,且很简单的利用对象不管在容器内或不在容器内。比方,Spring用户常常设置JakartaCommonsDBCP数据源为一个Springbean:不必要些任何定制代码往做这件事。我们说一个IoC容器不是侵进性的:利用它其实不会使你的代码依附于它的APIs。任何JavaBean在Springbeanfactory中都能成为一个组件。最初应当夸大的是,IoC分歧于传统的容器的系统布局,如EJB,使用代码最小水平地依托于容器。这意味着你的营业对象能够潜伏的被运转在分歧的IoC框架上——大概在任何框架以外——不必要任何代码的修改。以我和其他Spring用户的履历来讲,再怎样夸大IoC给使用程序代码带来的优点也不为过。IoC不是一个新观点,可是它在J2EE整体内里方才抵达黄金工夫。有一些可供选择的IoC容器:比方ApacheAvalon,PicoContainer和HiveMind。Avalon从没怎样盛行,只管它很壮大并且有很长的汗青。Avalon相称的重和庞大,而且看起来比新的IoC办理计划更具侵进性。PicoContainer是一个轻量级并且更夸大经由过程机关函数表达依附性而不是JavaBean属性。与Spring分歧,它的计划同意每一个范例一个对象的界说(多是由于它回绝任何Java代码外的元数据招致的范围性)。在Spring,PicoContainer和其他IoCframeworks之间做对照,可参看文章Spring网站上的"TheSpringFramework-ALightweightContainer"位于http://www.springframework.org/docs/lightweight_container.html。这个页面内里包括了PicoContainer站点的链接。SpringBeanFactories长短常轻量级的。用户已乐成地将他们使用在applets和独自的Swing使用中。(它们也很好地事情在EJB容器中。)没有特别的部署步骤和发觉失掉的启动工夫。这个才能标明一个容器在使用的任何层面几近当即能够发扬十分年夜的代价。SpringBeanFactory观点贯串于Spring一直,并且是Spring云云内涵分歧的关头缘故原由。在IoC容器中,Spring也是独一的,它利用IoC作为基本观点贯串于全部功效丰厚的框架。对使用开辟职员,最主要的是,一个或多个BeanFactory供应了一个界说明白的营业对象层。这相似于localsessionbean层,但比它更复杂。与EJBs分歧,在这个层中的对象多是相干的,而且他们的干系被具有它们的factory办理。有一个界说明白的营业对象层关于乐成的系统布局长短常主要的。SpringApplicationContext是BeanFactory的子接口,为以下工具供应撑持:信息查找,撑持着国际化事务机制,同意公布使用对象和可选的注册以吸收到事务可移植的文件和资本会见XmlBeanFactory例子Spring用户一般在XML的“bean界说”文件中设置他们的使用。Spring的XMLbean界说文档的根是<beans>元素。该元素包括一个或多个<bean>界说。我们一样平常给每一个bean界说的指定类和属性。我们还必需指定ID作为标识,这将成为在代码中利用该bean的名字。让我们来看一个复杂的例子,它设置了三个使用程序对象,之间的干系在J2EE使用中经常可以看到:J2EEDataSource利用DataSource的DAO在处置过程当中利用DAO的营业对象鄙人面的例子中,我们利用一个来自JakartaCommonsDBCP项目标BasicDataSource。这个class(和其他很多已有的class一样)能够复杂地被使用在Springbeanfactory中,只需它供应了JavaBean格局的设置。必要在shutdown时被挪用的Close办法可经由过程Spring的"destroy-method"属性被注册,以免BasicDataSource必要完成任何Spring的接口。代码:<beans><beanid="myDataSource"class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><propertyname="driverClassName"><value>com.mysql.jdbc.Driver</value></property><propertyname="url"><value>jdbc:mysql://localhost:3306/mydb</value></property><propertyname="username"><value>root</value></property></bean>BasicDataSource中我们感乐趣的一切属性都是String范例的,因而我们用<value>元从来指定他们的值。假如需要的话,Spring利用尺度的JavaBean属性编纂器机制来把String转换为其他的范例。如今,我们界说DAO,它有一个对DataSource的bean援用。Bean间干系经由过程<ref>元从来指定:代码:<beanid="exampleDataAccessObject"class="example.ExampleDataAccessObject"><propertyname="dataSource"><refbean="myDataSource"/></property></bean>ThebusinessobjecthasareferencetotheDAO,andanintproperty(exampleParam):<beanid="exampleBusinessObject"class="example.ExampleBusinessObject"><propertyname="dataAccessObject"><refbean="exampleDataAccessObject"/></property><propertyname="exampleParam"><value>10</value></property></bean></beans>对象间的干系一样平常在设置中明白地设置,象这个例子一样。我们以为如许做是件功德情。但是Spring还供应了我们称做"autowire"的撑持,一个laPicoContainer,个中它指出了bean间的依附干系。如许做的范围性——PicoContainer也是云云——是假如有一个特别范例的多个Bean,要断定谁人范例所依附的是哪一个实例是不成能。好的方面是,不满意的依附能够在factory初始化后被捕捉到。(Spring也为显式的设置供应了一种可选的依附反省,它能够完成这个目标)在下面的例子中,假如我们不想显式的编写他们的干系,可以使用以下的autowire特征:代码:<beanid="exampleBusinessObject"class="example.ExampleBusinessObject"autowire="byType"><propertyname="exampleParam"><value>10</value></property></bean>利用这个特征,Spring会找出exampleBusinessObject的dataSource属性应当被设置为在以后BeanFactory中找到的DataSource完成。在以后的BeanFactory中,假如所必要范例的bean不存在或多于一个,将发生一个毛病。我们仍然要设置exampleParam属性,由于它不是一个援用。Autowire撑持和依附反省方才到场CVS并将在Spring1.0M2(到10/20,2003)中供应。本文中所会商的一切其他特征都包括在以后1.0M1版本中。把办理从Java代码中移出来比硬编码有很年夜的优点,由于如许能够只改动XML文件而无需改动一行Java代码。比方,我们能够复杂地改动myDataSource的bean界说援用分歧的beanclass以利用其余毗连池,大概一个用于测试的数据源。XML节酿成另外一种,我们能够用Spring的JNDIlocationFactoryBean从使用服务器猎取一个数据源。如今让我们来看看例子中营业对象的java代码。注重上面列出的代码中没有对Spring的依附。不像EJB容器,SpringBeanFactory不具有侵进性:在使用对象内里你一般不必要对Spring的存在硬编码。代码:publicclassExampleBusinessObjectimplementsMyBusinessObject{privateExampleDataAccessObjectdao;privateintexampleParam;publicvoidsetDataAccessObject(ExampleDataAccessObjectdao){this.dao=dao;}publicvoidsetExampleParam(intexampleParam){this.exampleParam=exampleParam;}publicvoidmyBusinessMethod(){//dostuffusingdao}}注重那些propertysetter,它们对应于bean界说文档中的XML援用。这些将在对象被利用之前由Spring挪用。这些使用程序的bean不必要依附于Spring:他们不必要完成任何Spring的接口大概承继Spring的类。他们只必要恪守JavaBeans的定名习气。在Spring使用情况以外重用它们长短常复杂的,比方,在一个测试情况中。只必要用它们的缺省机关函数实例化它们,而且经由过程挪用setDataSource()和setExampleParam()手工设置它的属性。假如你想以一行代码撑持程序化的创立,只需你有一个无参数的机关器,你就能够自在界说其他必要多个属性的机关函数。注重在营业接口中没有声明将会一同利用的JavaBean属性。他们是一个完成细节。我们能够“拔出”带有分歧bean属性的分歧的完成类而不影响毗连着的对象大概挪用的代码。固然,SpringXMLbeanfactories有更多的功效没有在这里形貌,可是,应该让你对基础利用有了一些感到。和,复杂的属性,有JavaBean属性编纂器的属性,Spring能够主动处置lists,maps和java.util.Properties。Beanfactories和applicationcontexts一般和J2EEserver界说的一个局限相干联,比方:Servletcontext.:在spring的MVC框架里,每个包括commonobjects的web使用都界说有一个使用程序的context。Spring供应了经由过程listener大概servlet实例化如许的context的才能而不必要依附于Spring的MVC框架,因此它也能够用于Struts,WebWork大概其他的web框架当中。AServlet:在SpringMVC框架里每个servlet把持器都有它本人的使用程序context,派生于根(全使用程序局限的)使用程序context。在Struts大概其他MVC框架中完成这些也很容意。EJB:Spring为EJB供应便利的超类,它们简化了EJB的创立而且供应了一个从EJBJar文件中的XML文档载进的BeanFactory。这些J2EE标准供应的hook一般制止了利用Singleton来制造一个beanfactory。但是,假如我们乐意的话能够用代码创立一个BeanFactory,固然是没有甚么意义的。比方,我们在以下三行代码中能够创立beanfactory而且失掉一个营业对象的援用:代码:InputStreamis=getClass().getResourceAsStream("myFile.xml");XmlBeanFactorybf=newXmlBeanFactory(is);MyBusinessObjectmbo=(MyBusinessObject)bf.getBean("exampleBusinessObject");
这段代码将能事情在一个使用服务器以外:乃至不依附J2EE,由于Spring的IoC容器是纯java的。