Spring的web框架-外文翻译 下载本文

JDBC-related code can fully integrate transactionally with the code you use to do O/R mapping. This is useful for data access that's not suitable for O/R mapping, such as batch processing or streaming of BLOBs, which still needs to share common transactions with O/R mapping operations.

To avoid vendor lock-in, and allow mix-and-match implementation strategies. While Hibernate is powerful, flexible, open source and free, it still uses a proprietary API. Furthermore one could argue that iBATIS is a bit lightweight, although it's excellent for use in application that don't require complex O/R mapping strategies. Given the choice, it's usually desirable to implement major application functionality using standard or abstracted APIs, in case you need to switch to another implementation for reasons of functionality, performance, or any other concerns. For example, Spring's abstraction of Hibernate transactions and exceptions, along with its IoC approach which allows you to easily swap in mapper/DAO objects implementing data access functionality, makes it easy to isolate all Hibernate-specific code in one area of your application, without sacrificing any of the power of Hibernate. Higher level service code dealing with the DAOs has no need to know anything about their implementation. This approach has the additional benefit of making it easy to intentionally implement data access with a mix-and-match approach (i.e. some data access performed using Hibernate, and some using JDBC, others using iBATIS) in a non-intrusive fashion, potentially providing great benefits in terms of continuing to use legacy code or leveraging the strength of each technology.

The Spring transaction abstraction

Spring provides a consistent abstraction for transaction management. This abstraction is one of the most important of Spring's abstractions, and delivers the following benefits:

Provides a consistent programming model across different transaction APIs such as JTA, JDBC, Hibernate, iBATIS Database Layer and JDO.

Provides a simpler, easier to use, API for programmatic transaction management than most of these transaction APIs

Integrates with the Spring data access abstraction Supports Spring declarative transaction management

Traditionally, J2EE developers have had two choices for transaction management: to use global or local transactions. Global transactions are managed by the application server, using JTA. Local transactions are resource-specific: for example, a transaction associated with a JDBC connection. This choice had profound implications. Global transactions provide the ability to work with multiple transactional resources. (It's worth noting that most applications use a single transaction resource) With local transactions, the application server is not involved in transaction management, and cannot help ensure correctness across multiple resources.

Global transactions have a significant downside. Code needs to use JTA: a cumbersome API to use (partly due to its exception model). Furthermore, a JTA UserTransaction normally needs to be obtained from JNDI: meaning that we need to use both JNDI and JTA to use JTA. Obviously all use of global transactions limits the reusability of application code, as JTA is normally only available in an application server environment.

The preferred way to use global transactions was via EJB CMT (Container Managed Transaction): a form of declarative transaction management (as distinguished from programmatic transaction management). EJB CMT removes the need for transaction-related JNDI lookups--although of course the use of EJB itself necessitates the use of JNDI. It removes most--not all--need to write Java code to control transactions. The significant downside is that CMT is (obviously) tied to JTA and an application server environment; and that it's only available if we choose to implement business logic in EJBs, or at least behind a transactional EJB facade. The negatives around EJB in general are so great that this is not an attractive proposition, when there are alternatives for declarative transaction management.

Local transactions may be easier to use, but also have significant disadvantages: They cannot work across multiple transactional resources, and tend to invade the programming model. For example, code that manages transactions using a JDBC connection cannot run within a global JTA transaction.

Spring resolves these problems. It enables application developers to use a consistent programming model in any environment. You write your code once, and it can benefit from different transaction management strategies in different environments. Spring provides both declarative and programmatic transaction management. Declarative transaction management is preferred by most users, and recommended in most cases.

With programmatic transaction management developers work with the Spring transaction abstraction, which can run over any underlying transaction infrastructure. With the preferred declarative model developers typically write little or no code related to transaction management, and hence don't depend on Spring's or any other transaction API.

中文译文

Core包是框架的最基础部分, 并提供依赖注入(Dependency Injection)特性来使你可管理Bean容器功能。 这里的基础概念是BeanFactory,它提供Factory模式来消除对程序性单例的需要, 并允许你从程序逻辑中分离出依赖关系的配置和描述。

构建于Beans包上Context包,提供了一种框架式的Bean访问方式, 有些象JNDI注册。Context包的特性得自Beans包,并添加了文本消息的发送,通过比如资源串, 事件传播,资源装载的方式和Context的透明创建,如通过Servlet容器。

DAO包提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码。 该包也提供了一种方法实现编程性和声明性事务管理,不仅仅是针对实现特定接口的类, 而且对所有的POJO。

ORM包为流行的关系-对象映射APIs提供了集成层,包括JDO,Hibernate和iBatis。 通过ORM包,你可与所有Spring提供的其他特性相结合来使用这些对象/关系映射, 如前边提到的简单声明性事务管理。

Spring的AOP包提供与AOP联盟兼容的面向方面编程实现,允许你定义, 如方法拦截器和切点,来干净地给从逻辑上说应该被分离的功能实现代码解耦。 使用源码级的元数据功能,你可将各种行为信息合并到你的代码中,有点象.Net的attribute。

Spring的Web包提供了基本的面向Web的综合特性,如Multipart功能, 使用Servlet监听器的Context的初始化和面向Web的Applicatin Context。 当与WebWork或Struts一起使用Spring时,这个包使Spring可与其他框架结合。

Spring的Web MVC包提供了面向Web应用的Model-View-Controller实现。 Spring的MVC实现不仅仅是一种实现,它提供了一种domain model代码和web form的清晰分离, 这使你可使用Spring框架的所有其他特性,如校验.

Spring的web框架是围绕分发器(DispatcherServlet)设计的,DispatcherServlet将请求分发到不同的处理器,框架还包括可配置的处理器映射,视图解析,本地化,主题解析,还支持文件上传。缺省的处理器是一个简单的控制器(Controller)接口,这个接口仅仅定义了ModelAndViewhandleRequest(request,response)方法。你可以实现这个接口生成应用的控制器,但是使用Spring提供的一系列控制器实现会更好一些,比如AbstractController,AbstractCommandController,和SimpleFormController。应用控制器一般都从它们继承。注意你需要选择正确的基类:如果你没有表单,你就不需要一个FormController。这是和Structs的一个主要区别。

你可以使用任何对象作为命令对象或表单对象:不必实现某个接口或从某个基类继承。Spring的数据绑定相当灵活,例如,它认为类型不匹配这样的错误应该是应用级的验证错误,而不是系统错误。所以你不需要为了处理无效的表单提交,或者正确地转换字符串,在你的表单对象中用字符串类型重复定义你的业务对象属性。你应该直接绑定表单到业务对象

上。这是和Struts的另一个重要不同,Struts是围绕象Action和ActionForm这样的基类构建的,每一种行为都是它们的子类。

和WebWork相比,Spring将对象细分成不同的角色:它支持的概念有控制器(Controller),可选的命令对象(Command Object)或表单对象(Form Object),以及传递到视图的模型(Model)。模型不仅包含命令对象或表单对象,而且也包含任何引用数据。但是,WebWork的Action将所有的这些角色都合并在一个单独的对象里。WebWork允许你在表单中使用现有的业务对象,但是只能把它们定义成不同Action类的bean属性。更重要的是,在运算和表单赋值时,使用的是同一个处理请求的Action实例。因此,引用数据也需要被定义成Action的bean属性。这样在一个对象就承担了太多的角色。

对于视图:Spring的视图解析相当灵活。一个控制器实现甚至可以直接输出一个视图作为响应,这需要使用null返回ModelAndView。在一般的情况下,一个ModelAndView实例包含视图名字和模型映射表,模型映射表提供了bean的名字及其对象(比如命令对象或表单对象,引用数据等等)的对应关系。视图名解析的配置是非常灵活的,可以通过bean的名字,属性文件或者你自己的ViewResolver来实现。抽象的模型映射表完全抽象了表现层,没有任何限制:JSP,Velocity,或者其它的技术——任何表现层都可以直接和Spring集成。模型映射表仅仅将数据转换成合适的格式,比如JSP请求属性或者Velocity模版模型。

MVC实现的可扩展性

许多团队努力争取在技术和工具方面能使他们的投入更有价值,无论是现有的项目还是新的项目都是这样。具体地说,Struts 不仅有大量的书籍和工具,而且有许多开发者熟悉它。因此,如果你能忍受Struts的架构性缺陷,它仍然是web层一个很好的选择。WebWork和其它web框架也是这样。

如果你不想使用Spring的web MVC框架,而仅仅想使用Spring提供的其它功能,你可以很容易地将你选择的web框架和Spring结合起来。只要通过Spring的ContextLoadListener启动一个Spring的根应用上下文,并且通过它的ServletContext属性(或者Spring的各种帮助方法)在Struts或WebWork的Action中访问。注意到现在没有提到任何具体的“plugins”,因此这里也没有提及如何集成:从web层的角度看,你可以仅仅把Spring作为一个库使用,根应用上下文实例作为入口。

所有你注册的bean和Spring的服务可以在没有Spring的web MVC下被访问。Spring并没有在使用方法上和Struts或WebWork竞争,它只是提供单一web框架所没有的功能,从bean的配置到数据访问和事务处理。所以你可以使用Spring的中间层和(或者)数据访问层来增强你的应用,即使你只是使用象JDBC或Hibernate事务抽象这样的功能。

Spring MVC框架的特点

如果仅仅关注于web方面的支持,Spring有下面一些特点: