spring培训学习笔记_第1页
spring培训学习笔记_第2页
spring培训学习笔记_第3页
spring培训学习笔记_第4页
spring培训学习笔记_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

PAGEsSpring培训学习笔记spring概述 3控制反转,还是依赖注入 3面向方面编程 5一致性抽象 5事务管理 5测试 5与其它框架整合 5控制反转 6容器(container) 6IoC类型 6IoCinspring 7DIwithspring 11AOP 12定义 12Aop类型 13实现策略 13aop设计问题 13spring中的aop 14spring工作原理 14框架概述 14使用场景 15Bean工厂与应用程序上下文 18事物管理 20轻量级事务基础设施 20spring事务管理 20持久化 20数据访问策略 20持久化数据的缓存 21资源管理 21JDBC 21IBATISSQL 21HIBERANTE 21DAO 21远程调用 22RMI 22EJB 22JAX-RPC 22Hessian 22Burlap 22Web层设计 22设计目标 22集成struts 23测试 23单元测试 23可测试性 23测试驱动开发 24覆盖率分析与其他测试工具 24性能与可伸缩性 24定义 24设置清晰的目标 24体系结构的选择 25不同实现的选择 25调优和部署 25一种循证的性能策略 25Spring开发 25最佳实践 25参考 25spring概述Spring项目启动于2003年2月,其中基础代码来自《expertone-on-onej2eedesignanddevelopment》。Spring是指一个用于构造Java应用程序的轻量级框架,不限定于只编写web应用,最少侵入。Spring的核心是个轻量级(Lightweight)的容器(Container),它是实现IoC(InversionofControl)容器、非侵入性(Nointrusive)的框架,并提供AOP(Aspect-orientedprogramming)概念的实现方式,提供对持久层(Persistence)、事务(Transaction)的支持,提供MVCWeb框架的实现,并对一些常用的企业服务API(ApplicationInterface)提供一致的模型封装,是一个全方位的应用程序框架(Applicationframework),除此之外,对于现存的各种框架(Struts、JSF、Hibernate等),Spring也提供了与它们相整合的方案。本质上讲,Spring是IOC(InversionofControl)和面向切面编程(AOP)的组合体。它是一个非侵入式的框架,增强了POJO的功能。从服务上讲(Withaserviceabstraction),它将程序代码从J2EE环境解耦到普通的java对象(自然,这些代码可以脱离J2EE而在多种环境中运行)。它还在很多功能上提供了除EJB之外的选择――比如为所有的POJO提供声明式事务。Spring被广泛运用到很多项目中,从小的web程序到大的企业应用程序。控制反转,还是依赖注入Spring框架的核心基于“控制反转(InversionofControl,IoC)”原理。IoC是一种将组件依赖关系的创建和管理置于程序外部的技术。假设一个例子,类Foo依赖于类Bar的一个实例来进行某些操作。传统的方式,Foo使用new操作符创建一个Bar的实例,或者通过某种工厂类来获得。使用IoC方法,Bar的一个实例(或者其子类的实例)是通过某些外部处理过程在运行时动态传递给Foo的。这种在运行时注入依赖的行为方式,使得IoC后来被改称为另一个含义更明确的名字:“依赖注入(DependencyInjection,DI)”。Spring的DI实现是基于两个Java核心概念:JavaBean和Interface。当你使用DI的时候,你可以使得依赖配置与你的代码保持隔离。JavaBeans提供了一种创建Java资源的标准方法,并且这些资源是可以通过标准方式配置的。接口与DI是相互受益的技术,针对接口设计与编程有助于应用程序的灵活性,但要把采用接口设计的应用程序的各部分连接起来,其复杂度非常高,并且给开发者带来了额外的编码负担。通过采用DI,为基于接口的设计而编写的辅助代码大大减少了,近乎于零。反过来,通过采用接口,你可以获得DI的最大好处,因为你的bean可以采用任何满足其依赖的接口实现。减少“粘合”代码:DI带来的最大的好处之一就是,它可以奇迹般地消除你为了连接应用程序的各个部件而编写的大量代码。这些代码常常很简单而且琐碎——通过构造一个新的对象来创建依赖。然而,当你需要从JNDI库中查询依赖,或者这些调用不能直接通过调用产生时(比如访问远程资源),这些琐碎的代码可能会变得相当复杂。在这些情形下,DI真的可以简化粘合代码,因为它提供了自动的JNDI查询,以及对远程资源的自动代理。依赖外置化:你可以将依赖的配置外置,这样你可以无需重新编译代码就重新配置。这给你带来两个有趣的好处。首先,Spring中的DI是一种理想的配置方式,可以让你在外部自由的配置应用程序的所有选项。其次,依赖外置使得在不同的实现间切换变得非常容易。假设你有一个DAO组件,它针对PostgreSQL数据库进行数据操作,你想把它升级到Oracle。使用DI,你可以简单地重新配置你的业务对象的依赖关系,让它使用Oracle实现而非PostgreSQL实现。在统一的地方管理依赖:采用传统的方式管理依赖时,你在任何需要的地方创建依赖的对象实例——就在依赖者的内部。在大部分简单的程序中,你会让依赖关系在你的代码中散播,改变它们通常会带来问题。当使用DI的时候,所有关于依赖的信息都通过一个简单的库进行管理,使得管理依赖变得既简单又不容易出错。提高可测试性:当面向DI设计你的类时,你就可以便捷地替换依赖。当在测试程序的时候,这特别有用。假设一个业务对象进行某些复杂的处理,其中一部分它使用一个DAO对象来访问存储在关系数据库中的对象。在测试的时候,你对测试DAO本身不感兴趣,你只是简单地希望采用不同的数据集来测试你的业务对象。在通常的方式中,你的测试会变得很痛苦,因为你无法简单地把这个DAO实现替换为一个模拟实现,模拟返回你的测试数据。相反,你需要确认你的测试数据库中包含正确的数据,为你的测试使用完整的DAO实现。使用DI的话,你可以为你的DAO对象创建一个模拟实现,然后把它传递给你的业务对象进行测试。这种机制可以扩展到测试你的应用的任何一层,对测试web组件特别有用,你可以创建HttpServletRequest和HttpServeletResponse的模仿实现。鼓励良好的程序设计:针对DI设计意味着整体上针对接口设计。典型的基于注入的应用程序,其所有的主要组件都是定义为接口的,然后这些接口的具体实现采用DI容器创建并糅合到一起。在DI和基于DI的容器比如Spring出现之前,这种设计在Java中就是可行的,但是通过使用Spring,你免费获得了一个包含完整DI功能的基础,你可以集中精力于建立你的业务逻辑,而非关注支持业务的框架。面向方面编程AOP提供了实现横切逻辑的功能——这一逻辑应用于你应用程序的很多地方,只需要编写一次,就可以把这一逻辑自动在整个应用中实施目前有两种主流的AOP实现。静态AOP,比如AspectJ(),提供了编译器的方法来构建基于AOP的逻辑,并把它加入到应用程序中。动态AOP,比如Spring中的这样,允许在运行时把横切逻辑应用到任意一段代码中。两种不同的AOP方法都有其适用面,实际上,AOP提供了与AspectJ整合的功能。一致性抽象异常资源管理事务管理事务管理Spring提供了极好的事务管理抽象层,允许你进行编程式或者声明式事务控制。通过使用Spring的抽象层来进行事务,你可以很容易地抽换底层的数据访问协议和资源管理方式。你可以从一个简单的、本地的、单资源的事务管理起步,转移到全局的、多资源的事务管理环境,而无需更改你的代码。测试与其它框架整合在Spring中访问数据Spring中的JDBC支持使得编写基于JDBC的应用变得更加现实了,就算是比较复杂的应用程序也行。对Hibernate、iBATIS和JDO的支持让本就简单的API更加简化,减轻了开发者的负担,易于在同一程序中混合不同的数据访问技术。简化与整合J2EEWeb层的MVC远程访问(Remoting)支持Mail支持计划任务支持简化的异常处理源代码级的Metadata(元数据)控制反转容器(container)是指应用代码的运行框架。提供服务:生命周期管理查找服务配置服务依赖决议理想容器特点:可接插性一致性一站式购物提供企业级服务IoC类型typenamedescriptionType1InterfacedependentBeansmustimplementspecificinterfacestohavetheirdependenciesmanagedbythecontainer.Type2SetterinjectionDependenciesandpropertiesareconfiguredthroughabean’ssettermethods.Type3ConstructorinjectionDependenciesandpropertiesareconfiguredthroughthebean’sconstructor.依赖注入的基本原则:应用对象不应该负责查找资源或者其他依赖的协作组件。配置对象的工作应该由IoC容器完成,“查找资源”的逻辑应该从应用代码中抽取出来,交给容器负责。接口方法注入:组件通过接口的方式完成注入,具备侵入性,它要求组件必须与特定的接口相关联,因此并不被看好,实际使用有限。设值方法注入:组件通过javabean属性来表达自己需要配置的值和依赖的对象,建立在javabean规范之上。构造子注入:组件以构造子参数的形式描述自己需要的依赖关系。IoCinspringSpring的IoC控件主要专注于如何利用classes、对象和服务去组成一个企业级应用,通过规范的方式,将各种不同的控件整合成一个完整的应用。Spring中使用了很多被实践证明的最佳实践和正规的设计模式,并且进行了编码实现。如果你是一个,构架师或者开发人员完全可以取出它们集成到你自己的应用之中。这对于那些使用了SpringFramework的组织和机构来说,在spring基础上实现应用不仅可以构建优秀的,可维护的应用并对Spring的设计进行验证,确实是一件好事情。Spring框架所提供的众多功能之所以能成为一个整体正是建立在IoC的基础之上,org.springframework.beans及org.springframework.context包是SpringIoC容器的基础。BeanFactory提供的高级配置机制,使得管理任何性质的对象成为可能。ApplicationContext是BeanFactory的扩展,功能得到了进一步增强,比如更易与SpringAOP集成、消息资源处理(国际化处理)、事件传递及各种不同应用层的context实现(如针对web应用的WebApplicationContext)。简而言之,BeanFactory提供了配制框架及基本功能,而ApplicationContext则增加了更多支持企业核心内容的功能。ApplicationContext完全由BeanFactory扩展而来,因而BeanFactory所具备的能力和行为也适用于ApplicationContext。用户注册的例子 我们先看看更进一步的需求:实现一个用户注册信息持久化的类。功能:保存用户注册的信息;根据用户的名称获得该注册用户。虽然功能简单,但它对持久化方式的要求却非常的灵活:在内存中持久化,供测试、演示使用。如果用户的数据很少,将用户信息持据化到文本文件中。如果用户信息很多,并需要一些灵活的查询,则需要使用JDBC技术将用将用户信息持久化到数据库中。面对企业复杂关联的数据,甚至需要使用持久层框架来实现用户信息的持久化,比如:iBATIS、Hibernate等。如何去设计、实现我们这个持久化类呢?我们遵循软件开发的原则“首先让它跑起来,再去优化(重构)它”,我们首先实现最简单的在内存中持久化用户信息。 既然我们要保存和取得用户信息,首先应该设计用户类。代码如下:User.javapublicclassUser{privateLongid;privateStringname;privateStringpassword;privateStringgroup;publicUser(Stringname,Stringpassword){=name;this.password=password;}//相应的get/set方法………..}持久化类有两个方法,分别在内存中保存和获取User对象。代码如下:MemoryUserPersist.javapublicclassMemoryUserPersist{privatestaticMapusers=newHashMap();static{UserdefaultAdmin=newUser("Moxie","pass");users.put(defaultAdmin.getName(),defaultAdmin);}publicMemoryUserPersist(){}publicvoidsaveUser(Useruser){users.put(user.getName(),user);}publicUserLoadUser(StringuserName){return(User)users.get(userName);}}用户持久化类完成之后,我们就可以在客户端UserRegister中使用它了。例如:用户注册时,UserRegister代码片断如下:MemoryUserPersistuserPersist=newMemoryUserPersist();userPersist.saveUser(user); 可是,现在如果要在文本文件中持久化User,又该如何实现呢?实现一个TextUserPersist类,这个并不困难。但客户端代码将面临重大灾难:找到所有使用过MemoryUserPersist的客户端类,将他们中的MemoryUserPersist逐个手工修改为TextUserPersist,并且重新编译,当然以前的测试也必须全部从头来过! 人生的浩劫只是刚刚开始,因为根据前面的需求我们至少要分别实现四种持久化方式!这时,你一定和我一样在期待着救世主的早日降临——接口(Interface)。面向接口编程什么是接口?接口定义了行为的协议,这些行为在继承接口的类中实现。接口定义了很多方法,但是没有实现它们。类履行接口协议并实现所有定义在接口中的方法。接口是一种只有声明没有实现的特殊类。接口的优点:Client不必知道其使用对象的具体所属类。一个对象可以很容易地被(实现了相同接口的)的另一个对象所替换。对象间的连接不必硬绑定(hardwire)到一个具体类的对象上,因此增加了灵活性。松散藕合(loosenscoupling)。增加了重用的可能性。接口的缺点:设计的复杂性略有增加重构第一步——面向接口编程设计用户持久化类的接口UserDao,代码如下:publicinterfaceUserDao{publicvoidsave(Useruser);publicUserload(Stringname);}具体的持久化来必须要继承UserDao接口,并实现它的所有方法。我们还是首先实现内存持久化的用户类:publicclassMemoryUserDaoimplementsUserDao{privatestaticMapusers=newHashMap();;static{Useruser=newUser("Moxie","pass");users.put(user.getName(),user);}publicvoidsave(Useruser){users.put(user.getId(),user);}publicUserload(Stringname){return(User)users.get(name);}}MemoryUserDao的实现代码和上面的MemoryUserPersist基本相同,唯一区别是MemoryUserDao类继承了UserDao接口,它的save()和load()方法是实现接口的方法。这时,客户端UserRegister的代码又该如何实现呢?UserDaouserDao=newMemoryUserDao();userDao.save(user);(注:面向对象“多态”的阐述)如果我们再切换到文本的持久化实现TextUserDao,客户端代码仍然需要手工修改。虽然我们已经使用了面向对象的多态技术,对象userDao方法的执行都是针对接口的调用,但userDao对象的创建却依赖于具体的实现类,比如上面MemoryUserDao。这样我们并没有完全实现前面所说的“Client不必知道其使用对象的具体所属类”。如何解决客户端对象依赖具体实现类的问题呢?下面该是我们的工厂(Factory)模式出场了!重构第二步――工厂模式我们使用一个工厂类来实现userDao对象的创建,这样客户端只要知道这一个工厂类就可以了,不用依赖任何具体的UserDao实现。创建userDao对象的工厂类UserDaoFactory代码如下:publicclassUserDaoFactory{publicstaticUserDaocreateUserDao(){returnnewMemoryUserDao();}}客户端UserRegister代码片断如下:UserDaouserDao=UserDaoFactory.CreateUserDao();userDao.save(user);现在如果再要更换持久化方式,比如使用文本文件持久化用户信息。就算有再多的客户代码调用了用户持久化对象我们都不用担心了。因为客户端和用户持久化对象的具体实现完全解耦。我们唯一要修改的只是一个UserDaoFactory类。重构第三步——工厂(Factory)模式的改进到这里人生的浩劫已经得到了拯救。但我们仍不满足,因为假如将内存持久化改为文本文件持久化仍然有着硬编码的存在——UserDaoFactory类的修改。代码的修改就意味着重新编译、打包、部署甚至引入新的Bug。所以,我们不满足,因为它还不够完美!如何才是我们心目中的完美方案?至少要消除更换持久化方式时带来的硬编码。具体实现类的可配置不正是我们需要的吗?我们在一个属性文件中配置UserDao的实现类,例如:在属性文件中可以这样配置:userDao=com.test.MemoryUserDao。UserDao的工厂类将从这个属性文件中取得UserDao实现类的全名,再通过Class.forName(className).newInstance()语句来自动创建一个UserDao接口的具体实例。UserDaoFactory代码如下:publicclassUserDaoFactory{publicstaticUserDaocreateUserDao(){StringclassName="";//……从属性文件中取得这个UserDao的实现类全名。UserDaouserDao=null;try{userDao=(UserDao)Class.forName(className).newInstance();}catch(Exceptione){e.printStackTrace();}returnuserDao;}通过对工厂模式的优化,我们的方案已近乎完美。如果现在要更换持久化方式,不需要再做任何的手工编码,只要修改配置文件中的userDao实现类名,将它设置为你需要更换的持久化类名即可。我们终于可以松下一口气了?不,矛盾仍然存在。我们引入了接口,引入了工厂模式,让我们的系统高度的灵活和可配置,同时也给开发带来了一些复杂度:1、本来只有一个实现类,后来却要为这个实现类引入了一个接口。2、引入了一个接口,却还需要额外开发一个对应的工厂类。3、工厂类过多时,管理、维护非常困难。比如:当UserDao的实现类是JdbcUserDao,它使用JDBC技术来实现用户信息从持久化。也许要在取得JdbcUserDao实例时传入数据库Connection,这是仍少UserDaoFactory的硬编码。当然,面接口编程是实现软件的可维护性和可重用行的重要原则已经勿庸置疑。这样,第一个复杂度问题是无法避免的,再说一个接口的开发和维护的工作量是微不足道的。但后面两个复杂度的问题,我们是完全可以解决的:工厂模式的终极方案——IoC模式。重构第四步――IoC容器使用IoC容器,用户注册类UserRegister不用主动创建UserDao实现类的实例。由IoC容器主动创建UserDao实现类的实例,并注入到用户注册类中。我们下面将使用Spring提供的IoC容器来管理我们的用户注册类。用户注册类UserRegister的部分代码如下:publicclassUserRegister{privateUserDaouserDao=null;//由容器注入的实例对象publicvoidsetUserDao(UserDaouserDao){this.userDao=userDao;} //UserRegister的业务方法}在其它的UserRegister方法中就可以直接使用userDao对象了,它的实例由Spring容器主动为它创建。但是,如何组装一个UserDao的实现类到UserRegister中呢?哦,Spring提供了配置文件来组装我们的组件。Spring的配置文件applicationContext.xml代码片断如下:<beanid="userRegister"class="com.dev.spring.simple.UserRegister"> <propertyname="userDao"><reflocal="userDao"/></property></bean><beanid="userDao"class="com.dev.spring.simple.MemoryUserDao"/>DIwithspring典型的企业应用不会只由单一的对象(或bean)组成。毫无疑问,即使最简单的系统也需要多个对象一起来满足最终用户的需求。接下来的的内容除了阐述如何单独定义一系列bean外,还将描述如何让这些bean对象一起协同工作来实现一个完整的真实应用。依赖注入(DI)背后的基本原理是对象之间的依赖关系(即一起工作的其它对象)只会通过以下几种方式来实现:构造器的参数、工厂方法的参数,或给由构造函数或者工厂方法创建的对象设置属性。因此,容器的工作就是创建bean时注入那些依赖关系。相对于由bean自己来控制其实例化、直接在构造器中指定依赖关系或则类似服务定位器(ServiceLocator)模式这3种自主控制依赖关系注入的方法来说,控制从根本上发生了倒转,这也正是控制反转(InversionofControl,IoC)名字的由来。应用DI原则后,代码将更加清晰。而且当bean自己不再担心对象之间的依赖关系(以及在何时何地指定这种依赖关系和依赖的实际类是什么)之后,实现更高层次的松耦合将易如反掌。DI主要有两种注入方式,即\o".

Setter注入"Setter注入和\o".

构造器注入"构造器注入。AOPAop的目标是将横切性的问题以一种更加通用的方式模块化,从而提升程序的模块化程度。定义关注点(concern):一个关注点可以是一个特定的问题、概念、或是应用程序的兴趣区间――总而言之,应用程序必须达到的一个目标,在一个oo的应用程序中,关注点可能已经被代码模块化,也可能还散落在整个对象模型之中。横切关注点(crosscuttingconcern):如果一个关注点的实现代码散落在很多个类或方法之中,我们称之为“横切关注点”。方面(aspect):一个方面是对一个横切关注点的模块化,它将那些原本散落在各处的、用于实现这个关注点的代码规整到一处。连接点(joinpoint):程序执行过程中的一点,例如:方法调用(methodinvocation)字段访问(fieldaccess)异常抛出(throws)增强(advice):在特定连接点执行的动作。很多ao[框架都以拦截器的形式来表现增强――所谓拦截器就是当连接点被调用到时,它会收到一个回调消息。切入点(pointcut):一组连接点的总称,用于指定某个增强应该在何时被调用。引介(introduction):为一个现有的java类或接口添加方法或字段。混入继承(mixininheritance):一个“混入类”封装了一组功能,这组功能可以被“混入”到现有的类当中,并且无须求助于传统的继承手段。在aop这里,混入是通过引介来实现的。在java语言中,可以通过混入来模拟多继承。织入(weaving):将方面整合到完整的执行流程中。前增强(before,pre):在连接点调用之前,首先调用增强。后增强(after,post):在连接点调用之后,再调用增强。环绕增强(around):这类增强可以完全控制执行流程。拦截器(interceptor):用来实现字段和方法的拦截。Aop代理(aopproxy):即被增强的对象引用。目标对象(targetobject):位于拦截器链末端的对象实例。Aop类型therearetwodistincttypesofAOP:staticanddynamic.Thedifferencebetweenthemisreallythepointatwhichtheweavingprocessoccursandhowthisprocessisachieved.StaticAOPDynamicAOPChoosinganAOPType实现策略J2se动态代理(dynamicproxies):nanning动态字节码生成(dynamicbytecodegeneration):如CGLIBJava代码生成使用定制的类加载器:如jboss,aspectwerkz语言扩展:如aspectjaop设计问题字段的拦截:字段拦截会破坏封装,不建议使用。太多的方面:通过团队规范约束对方面的使用。正交性:如果你需要编写应用程序专用的方面,请尽量保持它们彼此独立,并且不要依赖于执行的先后顺序。使用aop应用程序如何测试:合理采用aop之后,单元测试就可以专注于检查业务逻辑是否实现正确,腺不必操心那些被模块化到方面中的基础设施问题。调试:取决于aop框架。是否严重影响性能:不会建议:以渐进式的、实用至上的方式来使用aop.Aop最有价值的用途就是在业务方法的粒度上提供通用的企业级服务,譬如声明性事务管理和声明性安全检查等。Aop和ioc之间有特别紧密的合作关系。spring中的aop简介@AspectJ支持Schema-basedAOPsupportAOP声明风格的选择混合切面类型代理机制编程方式创建@AspectJ代理在Spring应用中使用AspectJSpringAOPAPIsspring工作原理框架概述Core封装包是框架的最基础部分,提供IoC和依赖注入特性。这里的基础概念是BeanFactory,它提供对Factory模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置。构建于\o"3.1.

简介"Core封装包基础上的\o"3.8.

ApplicationContext"Context封装包,提供了一种框架式的对象访问方法,有些象JNDI注册器。Context封装包的特性得自于Beans封装包,并添加了对国际化(I18N)的支持(例如资源绑定),事件传播,资源装载的方式和Context的透明创建,比如说通过Servlet容器。\o"10.1.

简介"DAO提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码。并且,\o"11.1.

简介"JDBC封装包还提供了一种比编程性更好的声明性事务管理方法,不仅仅是实现了特定接口,而且对所有的POJOs(plainoldJavaobjects)都适用。\o"12.1.

简介"ORM封装包提供了常用的“对象/关系”映射APIs的集成层。其中包括\o"12.6.

JPA"JPA、\o"12.3.

JDO"JDO、\o"12.2.

Hibernate"Hibernate和\o"12.5.

iBATISSQLMaps"iBatis。利用ORM封装包,可以混合使用所有Spring提供的特性进行“对象/关系”映射,如前边提到的简单声明性事务管理。Spring的\o"6.1.

简介"AOP封装包提供了符合AOPAlliance规范的面向方面的编程(aspect-orientedprogramming)实现,让你可以定义,例如方法拦截器(method-interceptors)和切点(pointcuts),从逻辑上讲,从而减弱代码的功能耦合,清晰的被分离开。而且,利用source-level的元数据功能,还可以将各种行为信息合并到你的代码中,这有点象.Net的attribute的概念。Spring中的Web包提供了基础的针对Web开发的集成特性,例如多方文件上传,利用Servletlisteners进行IoC容器初始化和针对Web的applicationcontext。当与WebWork或Struts一起使用Spring时,这个包使Spring可与其他框架结合。Spring中的\o"13.1.

介绍"MVC封装包提供了Web应用的Model-View-Controller(MVC)实现。Spring的MVC框架并不是仅仅提供一种传统的实现,它提供了一种清晰的分离模型,在领域模型代码和webform之间。并且,还可以借助Spring框架的其他特性。使用场景借助搭积木方式来解释一下各种情景下使用Spring的情况,从简单的Applet一直到完整的使用Spring的事务管理功能和Web框架的企业应用。以下是典型的完整springweb应用:通过用Spring的\o"9.5.

声明式事务管理"声明事务管理特性,Web应用可以做到完全事务性,就像使用EJB提供的那种容器管理的事务一样。所有自定义的业务逻辑可以通过简单的POJO来实现,并利用Spring的IoC容器进行管理。对于其他的服务,比如发送email和不依赖web层的校验信息,还可以让你自己决定在哪里执行校验规则。Spring本身的ORM支持可以和JPA、Hibernate、JDO以及iBatis集成起来,例如使用Hibernate,你可复用已经存在的映射文件与标准的HibernateSessionFactory配置。用控制器去无缝整合web层和领域模型,消除对ActionForms的依赖,或者避免了其他class为领域模型转换HTTP参数的需要。使用了第三方框架的Spring中间层:有的时候,现有情况不允许你彻底地从一种框架切换到另一种框架。然而,Spring却不需要强制你使用它的全部,Spring不是一种全有全无的解决方案。如果,现有的应用使用了WebWork、Struts、Tapestry或其他的UI框架作为前端程序,完全可以只与Spring的事务特性进行集成。只需要使用ApplicationContext来挂接你的业务逻辑和通过WebApplicationContext来集成你的web层前端程序。远程使用场景:当你需要通过WebService来访问你的现有代码时,你可使用Spring提供的Hessian-、Burlap-、Rmi-为前缀的接口或者JaxRpcProxyFactory这个代理类。你会发现,远程访问现有应用程序不再那么困难了。EJBs-包装现有的POJOs:Spring还为EJB提供了\o"第

18

EnterpriseJavaBean(EJB)集成"数据访问和抽象层,让你可以复用已存在的POJO并将他们包装在无状态SessionBean中,以便在可能需要声明式安全(EJB中的安全管理,译者注)的非安全的Web应用中使用。Bean工厂与应用程序上下文BeanFactoryApplicationContextBeanFactory是Spring的“心脏”。它就是SpringIoC容器的真面目。Spring使用BeanFactory来实例化、配置和管理Bean。但是,在大多数情况我们并不直接使用BeanFactory,而是使用ApplicationContext。它也是BeanFactory的一个实现,但是它添加了一系列“框架”的特征,比如:国际化支持、资源访问、事件传播等。ApplicationContext我们将在后面章节中介绍。ApplicationContextBeanFactoryBeanFactoryBeanFactory其实是一个接口-org.springframework.beans.factory.BeanFactory,它可以配置和管理几乎所有的Java类。当然,具体的工作是由实现BeanFactory接口的实现类完成。我们最常用的BeanFactory实现是org.springframework.beans.factory.xml.XmlBeanFactory。它从XML文件中读取Bean的定义信息。当BeanFactory被创建时,Spring验证每个Bean的配置。当然,要等Bean创建之后才能设置Bean的属性。单例(Singleton)Bean在启动时就会被BeanFactory实例化,其它的Bean在请求时创建。根据BeanFactory的Java文档(Javadocs)介绍,“Bean定义的持久化方式没有任何的限制:LDAP、RDBMS、XML、属性文件,等等”。现在Spring已提供了XML文件和属性文件的实现。无疑,XML文件是定义Bean的最佳方式。BeanFactory是初始化Bean和调用它们生命周期方法的“吃苦耐劳者”。注意,BeanFactory只能管理单例(Singleton)Bean的生命周期。它不能管理原型(prototype,非单例)Bean的生命周期。这是因为原型Bean实例被创建之后便被传给了客户端,容器失去了对它们的引用。BeanFactory管理Bean(组件)的生命周期下图描述了Bean的生命周期。它是由IoC容器控制。IoC容器定义Bean操作的规则,即Bean的定义(BeanDefinition)。Bean的定义包含了BeanFactory在创建Bean实例时需要的所有信息。BeanFactory首先通过构造函数创建一个Bean实例,之后它会执行Bean实例的一系列之前初始化动作,初始化结束Bean将进入准备就绪(ready)状态,这时应用程序就可以获取这些Bean实例了。最后,当你销毁单例(Singleton)Bean时,它会调用相应的销毁方法,结束Bean实例的生命周期。(图-Bean的生命周期)事物管理事务是所有企业应用系统的核心。事务基础设施的目标在于让开发应用系统的程序员无需关注底层的事务处理,让数据访问对象仅包括实际的数据存取代码,而不需要编写事务处理代码。轻量级事务基础设施可编程的事务声明和一致的异常处理机制。在POJO上面实现的声明式事务,无需绑定到象ejb这样的重量级组件模型上。可插入的事务策略,以及让资源能够自动加入事务的手段。spring事务管理事务声明编程式事务处理:一是在一个catch代码块中对任何异常时行回滚处理;二是通过一个IoC模板类和一个回调实现。声明式事务处理:最适合用AOP,回事务管理有一个很明确的横切概念。事务管理策略持久化数据访问策略a.基于数据集的SQL访问(set-basedSQLaccess)b.带有透明持久化功能的O/R映射(O/Rmappingwithtransparentpersistence)何时选择O/R映射一个好的O/R映射解决方案可以成功的弥合对象与关系结构之间的“阻抗不匹配”,使业务对象能够与持久化的领域对象协同工作,并且使得java开发者不必使用SQL工作。针对领域对象的“加载/编辑/存储”流程对象以批量查询的方式取出,但更新和删除则是单独进行大量对象需要积极地缓存在领域对象与数据库表/字段之间有一个相当自然的对应关系不需要对SQL进行特别的优化持久化数据的缓存资源管理连接工厂:这个工厂代表了一种特定的数据存储介质,通过它可以创建连接。连接工厂通常是一个线程安全的实例,可以从JNDI或者O/R映射产品提供的全局工厂获得。之于JDBC,扮演这个角色的是DataSource;之于JDO是PersistenceManagerFactory;之于Hibernate是SessionFactory。连接:这个对象代表了与特定数据存储介质之间的通信会话。连接通常不是线程安全的,因此每次会话都会从连接工厂新建一个连接。之于JDBC,代表连接的是Connection对象;之于JDO是PersistenceManager;之于Hibernate是Session;之于TopLink可能是Session或UnitOfWork。JDBC在SQL层面上操作关系数据库,它是公认的、强大的API。主要缺点在于,如果直接使用它,需要编写很多重复的基础设施代码。IBATISSQLSQL语句在XML文件中定义,并预留参数占位符,在执行时,占位符将被指定

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论