Spring Framework 4.x Reference Documentation 中文翻译

m1230ok

贡献于2015-09-11

字数:0 关键词: Spring JEE框架

1. Introduction 2. I. Spring Framework 总览 i. 1. 开始 Spring ii. 2. 介绍 Spring Framework i. 2.1. 依赖注入和控制反转 ii. 2.2. 模块 iii. 2.3. 使用场景 iii. II. Spring Framework 4.x 新特性 iv. 3. Spring Framework 4.0中的新功能和增强功能 i. 3.1. Improved Getting Started Experience ii. 3.2. Removed Deprecated Packages and Methods iii. 3.3. Java 8 (as well as 6 and 7) iv. 3.4. Java EE 6 and 7 v. 3.5. Groovy Bean Definition DSL vi. 3.6. Core Container Improvements vii. 3.7. General Web Improvements viii. 3.8. WebSocket, SockJS, and STOMP Messaging ix. 3.9. Testing Improvements v. 4. Spring Framework 4.1中的新功能和增强功能 i. 4.1. JMS Improvements ii. 4.2. Caching Improvements iii. 4.3. Web Improvements iv. 4.4. WebSocket STOMP Messaging Improvements v. 4.5. Testing Improvements vi. III. Core Technologies vii. 5. The IoC container i. 5.1. Introduction to the Spring IoC container and beans ii. 5.2. Container overview iii. 5.3. Bean overview iv. 5.4. Dependencies v. 5.5. Bean scopes vi. 5.6. Customizing the nature of a bean vii. 5.7. Bean definition inheritance viii. 5.8. Container Extension Points ix. 5.10. Classpath scanning and managed components x. 5.11. Using JSR 330 Standard Annotations xi. 5.12. Java-based container configuration xii. 5.13. Environment abstraction xiii. 5.14. Registering a LoadTimeWeaver xiv. 5.15. Additional Capabilities of the ApplicationContext xv. 5.16. The BeanFactory viii. 6. Resources i. 6.1. Introduction ii. 6.2. The Resource interface iii. 6.3. Built-in Resource implementations iv. 6.4. The ResourceLoader v. 6.5. The ResourceLoaderAware interface vi. 6.6. Resources as dependencies vii. 6.7. Application contexts and Resource paths Table of Contents Spring Framework 4.x Reference Documentation 中文翻译 2 ix. 7. Validation, Data Binding, and Type Conversion i. 7.1. Introduction ii. 7.2. Validation using Spring’s Validator interface iii. 7.3. Resolving codes to error messages iv. 7.4. Bean manipulation and the BeanWrapper v. 7.5. Spring Type Conversion vi. 7.6. Spring Field Formatting vii. 7.7. Configuring a global date & time format viii. 7.8. Spring Validation x. 8. Spring Expression Language-SpEL i. 8.1. Introduction ii. 8.2. Feature Overview iii. 8.3. Expression Evaluation using Spring’s Expression Interface iv. 8.4. Expression support for defining bean definitions v. 8.5. Language Reference vi. 8.6. Classes used in the examples xi. 9. Aspect Oriented Programming with Spring i. 9.1. Introduction ii. 9.2. @AspectJ support iii. 9.3. Schema-based AOP support iv. 9.4. Choosing which AOP declaration style to use v. 9.5. Mixing aspect types vi. 9.6. Proxying mechanisms vii. 9.7. Programmatic creation of @AspectJ Proxies viii. 9.8. Using AspectJ with Spring applications ix. 9.9. Further Resources xii. 10. Spring AOP APIs i. 10.1. Introduction ii. 10.2. Pointcut API in Spring iii. 10.3. Advice API in Spring iv. 10.4. Advisor API in Spring v. 10.5. Using the ProxyFactoryBean to create AOP proxies vi. 10.6. Concise proxy definitions vii. 10.7. Creating AOP proxies programmatically with the ProxyFactory viii. 10.8. Manipulating advised objects ix. 10.9. Using the "auto-proxy" facility x. 10.10. Using TargetSources xi. 10.11. Defining new Advice types xii. 10.12. Further resources xiii. 11. Testing i. 11.1. Introduction to Spring Testing ii. 11.2. Unit Testing iii. 11.3. Integration Testing iv. 11.4. Further Resources xiv. IV. 数据访问 xv. 12. Transaction Management i. 12.1. Introduction to Spring Framework transaction management ii. 12.2. Advantages of the Spring Framework’s transaction support model iii. 12.3. Understanding the Spring Framework transaction abstraction iv. 12.4. Synchronizing resources with transactions v. 12.5. Declarative transaction management vi. 12.6. Programmatic transaction management vii. 12.7. Choosing between programmatic and declarative transaction management Spring Framework 4.x Reference Documentation 中文翻译 3 viii. 12.8. Application server-specific integration ix. 12.9. Solutions to common problems x. 12.10. Further Resources xvi. 13. DAO support i. 13.1. Introduction ii. 13.2. Consistent exception hierarchy iii. 13.3. Annotations used for configuring DAO or Repository classes xvii. 14. Data access with JDBC i. 14.1. Introduction to Spring Framework JDBC ii. 14.2. Using the JDBC core classes to control basic JDBC processing and error handling iii. 14.3. Controlling database connections iv. 14.4. JDBC batch operations v. 14.5. Simplifying JDBC operations with the SimpleJdbc classes vi. 14.6. Modeling JDBC operations as Java objects vii. 14.7. Common problems with parameter and data value handling viii. 14.8. Embedded database support ix. 14.9. Initializing a DataSource xviii. 15. 对象关系映射(ORM)数据访问 i. 15.1. Spring 中的 ORM ii. 15.2. 常见的 ORM 集成方面的注意事项 iii. 15.3. Hibernate iv. 15.4. JDO v. 15.5. JPA xix. 16. Marshalling XML using O/X Mappers i. 16.1. Introduction ii. 16.2. Marshaller and Unmarshaller iii. 16.3. Using Marshaller and Unmarshaller iv. 16.4. XML Schema-based Configuration v. 16.5. JAXB vi. 16.6. Castor vii. 16.7. XMLBeans viii. 16.8. JiBX ix. 16.9. XStream 3. V. The Web i. 17. Web MVC framework i. 17.1. Introduction to Spring Web MVC framework ii. 17.2. The DispatcherServlet iii. 17.3. Implementing Controllers iv. 17.4. Handler mappings v. 17.5. Resolving views vi. 17.6. Using flash attributes vii. 17.7. Building URIs viii. 17.8. Using locales ix. 17.9. Using themes x. 17.10. Spring’s multipart (file upload) support xi. 17.11. Handling exceptions xii. 17.12. Web Security xiii. 17.13. Convention over configuration support xiv. 17.14. ETag support xv. 17.15. Code-based Servlet container initialization xvi. 17.16. Configuring Spring MVC ii. 18. View technologies i. 18.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 4 ii. 18.2. JSP & JSTL iii. 18.3. Tiles iv. 18.4. Velocity & FreeMarker v. 18.5. XSLT vi. 18.6. Document views (PDF/Excel) vii. 18.7. JasperReports viii. 18.8. Feed Views ix. 18.9. XML Marshalling View x. 18.10. JSON Mapping View xi. 18.11. XML Mapping View iii. 19. Integrating with other web frameworks i. 19.1. Introduction ii. 19.2. Common configuration iii. 19.3. JavaServer Faces 1.2 iv. 19.4. Apache Struts 2.x v. 19.5. Tapestry 5.x vi. 19.6. Further Resources iv. 20. Portlet MVC Framework i. 20.1. Introduction ii. 20.2. The DispatcherPortlet iii. 20.3. The ViewRendererServlet iv. 20.4. Controllers v. 20.5. Handler mappings vi. 20.6. Views and resolving them vii. 20.7. Multipart (file upload) support viii. 20.8. Handling exceptions ix. 20.9. Annotation-based controller configuration x. 20.10. Portlet application deployment v. 21. WebSocket Support i. 21.1. Introduction ii. 21.2. WebSocket API iii. 21.3. SockJS Fallback Options iv. 21.4. STOMP Over WebSocket Messaging Architecture 4. VI. Integration i. 22. Remoting and web services using Spring i. 22.1. Introduction ii. 22.2. Exposing services using RMI iii. 22.3. Using Hessian or Burlap to remotely call services via HTTP iv. 22.4. Exposing services using HTTP invokers v. 22.5. Web services vi. 22.6. JMS vii. 22.7. AMQP viii. 22.8. Auto-detection is not implemented for remote interfaces ix. 22.9. Considerations when choosing a technology x. 22.10. Accessing RESTful services on the Client ii. 23. Enterprise JavaBeans (EJB) integration i. 23.1. Introduction ii. 23.2. Accessing EJBs iii. 23.3. Using Spring’s EJB implementation support classes iii. 24. JMS (Java Message Service) i. 24.1. Introduction ii. 24.2. Using Spring JMS iii. 24.3. Sending a Message Spring Framework 4.x Reference Documentation 中文翻译 5 iv. 24.4. Receiving a message v. 24.5. Support for JCA Message Endpoints vi. 24.6. Annotation-driven listener endpoints vii. 24.7. JMS Namespace Support iv. 25. JMX i. 25.1. Introduction ii. 25.2. Exporting your beans to JMX iii. 25.3. Controlling the management interface of your beans iv. 25.4. Controlling the ObjectNames for your beans v. 25.5. JSR-160 Connectors vi. 25.6. Accessing MBeans via Proxies vii. 25.7. Notifications viii. 25.8. Further Resources v. 26. JCA CCI i. 26.1. Introduction ii. 26.2. Configuring CCI iii. 26.3. Using Spring’s CCI access support iv. 26.4. Modeling CCI access as operation objects v. 26.5. Transactions vi. 27. Email i. 27.1. Introduction ii. 27.2. Usage iii. 27.3. Using the JavaMail MimeMessageHelper vii. 28. Task Execution and Scheduling i. 28.1. Introduction ii. 28.2. The Spring TaskExecutor abstraction iii. 28.3. The Spring TaskScheduler abstraction iv. 28.4. Annotation Support for Scheduling and Asynchronous Execution v. 28.5. The Task Namespace vi. 28.6. Using the Quartz Scheduler viii. 29. Dynamic language support i. 29.1. Introduction ii. 29.2. A first example iii. 29.3. Defining beans that are backed by dynamic languages iv. 29.4. Scenarios v. 29.5. Bits and bobs vi. 29.6. Further Resources ix. 30. Cache Abstraction i. 30.1. Introduction ii. 30.2. Understanding the cache abstraction iii. 30.3. Declarative annotation-based caching iv. 30.4. JCache (JSR-107) annotations v. 30.5. Declarative XML-based caching vi. 30.6. Configuring the cache storage vii. 30.7. Plugging-in different back-end caches viii. 30.8. How can I set the TTL/TTI/Eviction policy/XXX feature? 5. VII. Appendices i. 31. Migrating to Spring Framework 4.0 ii. 32. Classic Spring Usage i. 32.1. Classic ORM usage ii. 32.2. Classic Spring MVC iii. 32.3. JMS Usage iii. 33. Classic Spring AOP Usage Spring Framework 4.x Reference Documentation 中文翻译 6 i. 33.1. Pointcut API in Spring ii. 33.2. Advice API in Spring iii. 33.3. Advisor API in Spring iv. 33.4. Using the ProxyFactoryBean to create AOP proxies v. 33.5. Concise proxy definitions vi. 33.6. Creating AOP proxies programmatically with the ProxyFactory vii. 33.7. Manipulating advised objects viii. 33.8. Using the "autoproxy" facility ix. 33.9. Using TargetSources x. 33.10. Defining new Advice types xi. 33.11. Further resources iv. 34. XML Schema-based configuration i. 34.1. Introduction ii. 34.2. XML Schema-based configuration v. 35. Extensible XML authoring i. 35.1. Introduction ii. 35.2. Authoring the schema iii. 35.3. Coding a NamespaceHandler iv. 35.4. BeanDefinitionParser v. 35.5. Registering the handler and the schema vi. 35.6. Using a custom extension in your Spring XML configuration vii. 35.7. Meatier examples viii. 35.8. Further Resources vi. 36. spring.tld i. 36.1. Introduction ii. 36.2. the bind tag iii. 36.3. the escapeBody tag iv. 36.4. the hasBindErrors tag v. 36.5. the htmlEscape tag vi. 36.6. the message tag vii. 36.7. the nestedPath tag viii. 36.8. the theme tag ix. 36.9. the transform tag x. 36.10. the url tag xi. 36.11. the eval tag vii. 37. spring-form.tld i. 37.1. Introduction ii. 37.2. the checkbox tag iii. 37.3. the checkboxes tag iv. 37.4. the errors tag v. 37.5. the form tag vi. 37.6. the hidden tag vii. 37.7. the input tag viii. 37.8. the label tag ix. 37.9. the option tag x. 37.10. the options tag xi. 37.11. the password tag xii. 37.12. the radiobutton tag xiii. 37.13. the radiobuttons tag xiv. 37.14. the select tag xv. 37.15. the textarea tag Spring Framework 4.x Reference Documentation 中文翻译 7 Chinese translation of the [Spring Framework 4.x Reference Documentation] (http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/). The current version of the Spring Framework 4.x Reference Documentation is 4.1.6.RELEASE. This is also a GitBook version of the book: http://waylau.gitbooks.io/spring-framework-4-reference. Let's go! 《Spring Framework 4.x参考文档》中文翻译(包含了官方文档以及其他文章)。至今为止,Spring Framework 的最新版本 为 4.1.6.RELEASE。 利用业余时间对此进行翻译,并在原文的基础上,插入配图,图文并茂方便用户理解。如有勘误欢迎指正,点此提问。如有 兴趣,也可以参与到本翻译工作中来 :) 从目录开始阅读吧 Blog:www.waylau.com Gmail: waylau521@gmail.com Weibo: waylau521 Twitter: waylau521 Github : waylau spring-framework-4-reference Contact: Spring Framework 4.x Reference Documentation 中文翻译 8Introduction Spring Framework 是一个轻量级的解决方案,可以一站式构建企业级应用。然而,Spring 是模块化的,允许你使用的你需 要的部分,而不必把其余带进来。你可以在任何框架之上去使用IOC容器,但你也可以只使用 Hibernate 集成代码 或 JDBC 抽象层。Spring Framework 支持声明式事务管理,通过 RMI 或 Web 服务远程访问你的逻辑,并支持多种选择持久化你的数 据。它提供了一个全功能的 MVC 框架,使您能够将 AOP 透明地集成到您的软件。 Spring 的设计是非侵入性的,也就是说你的领域逻辑代码一般对框架本身无依赖性。在你的集成层(如数据访问层),在数 据访问技术和 Spring 的库一些依赖将存在。然而,它应该很容易从你的剩余代码中分离这些依赖。 本文档是 Spring Framework 功能的参考指南。如果你有关于这个文档的任何要求,意见或问题,请发送到用户邮件列表。 对 Framework 本身的问题应该到 StackOverflow 请问(见https://spring.io/questions) 译者注:对本文档的翻译有任何问题,请在https://github.com/waylau/spring-framework-4-reference/issues上面提问 Part I. Overview of Spring Framework 总览 Spring Framework 4.x Reference Documentation 中文翻译 9I. Spring Framework 总览 本参考指南提供了关于 Spring Framework 的详细信息。提供它的所有功能全面的文档,以及Spring所涵盖的一些关于底层 方面的背景资料(如“Dependency Injection(依赖注入)”)。 如果你是刚刚开始 Spring,你可能要开始使用 Spring Framework 创建一个基于 Spring Boot 的应用。Spring Boot 提供了一 种快速(自用)的方法来创建一个生产准备基于 Spring 的应用程序。它是基于Spring Framework,约定大于配置,为了让 你尽快地运行内。 您可以使用 start.spring.io 生产一个基本项目或遵循一个类似 Getting Started Building a RESTful Web Service的“入门”指 南。这些指南都非常专注于任务,其中大部分是基于 Spring Boot,非常容易理解。这些还涵盖了你可能想解决一个特定问题 时要考虑到的 spring 其他项目。 1. Getting Started with Spring 开始 Spring Framework 4.x Reference Documentation 中文翻译 101. 开始 Spring Spring Framework 是一个提供完善的基础支持来开发 Java 应用程序的Java 平台。Spring 负责基础功能,让您可以专注于 您的应用。 Spring 可以使你从“简单的Java对象”(POJO)构建应用程序,并且将企业服务非侵入性的应用到 POJO。此功能适用于 Java SE 编程模型和完全或者部分的 Java EE 。 举例,作为一个应用程序的开发者,你可以从 Spring 平台获得以下效益: 不用去处理事务 API 而使 Java 方法可以执行数据库事务。 不用去处理远程 API 而使本地 Java 方法可以执行远程过程。 不用去处理 JMX API 而使本地 Java 方法可以拥有管理操作。 不用去处理 JMS API 而使本地 Java 方法可以执行消息处理。 2. Introduction to the Spring Framework 介绍 Spring Framework 4.x Reference Documentation 中文翻译 112. 介绍 Spring Framework Java 应用程序--运行在各个松散的领域,从受限的嵌入式应用程序,到 n 层架构的服务端企业级应用程序--通常由来自应用适当 的对象进行组合合作。因此,对象在应用程序中是彼此依赖。 尽管 Java 平台提供了丰富的应用程序开发功能,但它缺乏来组织基本构建块成为一个完整的方法。这个任务留给了架构师和 开发人员。虽然您可以使用设计模式,例如 Factory, Abstract Factory, Builder, Decorator, 和 Service Locator 来组合各种类和 对象实例构成应用程序,这些模式是:给出一个最佳实践的名字,描述什么模式,哪里需要应用它,它要解决什么问题,等等。模式 是形式化的最佳实践,但你必须在应用程序中自己来实现。 Spring Framework 的 Inversion of Control (IoC) 组件旨在通过提供正规化的方法来组合不同的组件成为一个完整的可用的应 用。 Spring Framework 将规范化的设计模式作为一等的对象,您可以集成到自己的应用程序。许多组织和机构使用 Spring Framework 以这种方式来开发健壮的、可维护的应用程序。 背景 “问题是,[他们]哪些方面的控制被反转?”这个问题由 Martin Fowler在他的 Inversion of Control (IoC) 网站在 2004 年提出。 Fowler 建议重新命名这个说法,使得他更加好理解,并且提出了 Dependency Injection(依赖注入)(这个新的说法)。 译者注:Dependency Injection 和 Inversion of Control 其实就是一个东西的两种不同的说法而已。本质上是一回事。 2.1 Dependency Injection and Inversion of Control 依赖注 入和控制反转 Spring Framework 4.x Reference Documentation 中文翻译 122.1. 依赖注入和控制反转 Spring Framework 的功能被组织成了 20 来个模块。这些模块分成 Core Container, Data Access/Integration, Web, AOP (Aspect Oriented Programming), Instrumentation, Messaging, 和 Test,如下图: Figure 2.1. Overview of the Spring Framework 下面章节会列出可用的模块,名称与功能及他们的主题相关。组件名称与组件的 ID 相关,用于2.3.1节中的依赖管理工具。 Core Container 由 spring-core, spring-beans, spring-context, spring-context-support, 和 spring-expression (Spring Expression Language) 模块组成 spring-core 和 spring-beans 提供框架的基础部分,包括 IoC 和 Dependency Injection 功能。BeanFactory 是一个复杂的工 厂模式的实现。不需要可以编程的单例,并允许您将配置和特定的依赖从你的实际程序逻辑中解耦。 Context (spring-context) 模块建立且提供于在Core 和 Beans 模块的基础上,它是一种在框架类型下实现对象存储操作的手 段,有一点像 JNDI 注册。Context 继承了 Beans 模块的特性,并且增加了对国际化的支持(例如用在资源包中)、事件广 播、资源加载和创建上下文(例如 一个 Servlet 容器)。Context 模块也支持例如 EJB,JMX 和基础远程这样的 JavaEE 特 性。ApplicationContext 是 Context 模块的焦点。spring-context-support 提供对常见第三方库的支持集成进 Spring 应用上下 文,如缓存 (EhCache, Guava, JCache), 通信 (JavaMail), 调度 (CommonJ, Quartz) 和 模板引擎 (FreeMarker, JasperReports, Velocity). spring-expression 模块提供了一个强大的Expression Language(表达式语言)用来在运行时查询和操作对象图。这是作为 2.2 Modules 模块 2.2.1 Core Container 核心容器 Spring Framework 4.x Reference Documentation 中文翻译 132.2. 模块 JSP2.1 规范所指定的统一表达式语言(unified EL)的一种延续。这种语言支持对属性值、属性参数、方法调用、数组内容 存储、收集器和索引、逻辑和算数操作及命名变量,并且通过名称从 Spring 的控制反转容器中取回对象。表达式语言模块也 支持 List 的映射和选择,正如像常见的列表汇总一样。 spring-aop 模块提供 AOP Alliance-compliant(联盟兼容)的面向切面编程实现,允许你自定义,比如,方法拦截器和切入 点完全分离代码。使用源码级别元数据的功能,你也可以在你的代码中加入 behavioral information (行为信息),在某种程度 上类似于 .NET 属性。 单独的 spring-aspects 模块提供了集成使用 AspectJ。 spring-instrument 模块提供了类 instrumentation 的支持和再某些应用程序服务器使用类加载器实现。 Spring Framework 4 包含了 spring-messaging 模块,从 Spring 集成项目中抽象出来,比如 Message, MessageChannel, MessageHandler 及其他用来提供基于消息的基础服务。该模块还包括一组消息映射方法的注解,类似于基于编程模型 Spring MVC 的注解。 Data Access/Integration 层由 JDBC, ORM, OXM, JMS, 和 Transaction 模块组成。 spring-jdbc 模块提供了不需要编写冗长的JDBC代码和解析数据库厂商特有的错误代码的JDBC-抽象层。 spring-tx 模块的支持可编程和声明式事务管理,用于实现了特殊的接口的和你所有的POJO类(Plain Old Java Objects)。 spring-orm 模块提供了流行的 object-relational mapping(对象-关系映射)API集成层,其包含 JPA,JDO,Hibernate。使 用ORM包,你可以使用所有的 O/R 映射框架结合所有Spring 提供的特性,比如前面提到的简单声明式事务管理功能。 spring-orm 模块提供抽象层用于支持 Object/XML mapping (对象/XML映射)的实现,如 JAXB、Castor、XMLBeans、JiBX 和 XStream 的。 spring-jms 模块(Java Messaging Service)包含生产和消费信息的功能。 从 Spring Framework 4.1 开始提供集成 spring- messaging 模块。 Web 层由 spring-web, spring-webmvc, spring-websocket, 和 spring-webmvc-portlet 组成 。 spring-web 模块提供了基本的面向 web 开发的集成功能,例如多方文件上传、使用 Servlet listeners 和 Web 开发应用程序 上下文初始化 IoC 容器。它也包含 HTTP 客户端以及 Spring 远程访问的支持的 web 相关的部分。 spring-webmvc 模块(也被称为 Web Servlet 模块)包含 Spring 的model-view-controller (模型-视图-控制器(MVC)和 REST Web Services 实现的Web应用程序。Spring 的 MVC 框架提供了domain model(领域模型)代码和 web form (网页) 之间的完全分离,并且集成了 Spring Framework 所有的其他功能。 spring-webmvc-portlet 模块(也被称为 Web-Portlet 模块)提供了MVC 模式的实现是用一个 Portlet 的环境和 spring- webmvc 模块功能的镜像。 spring-test 模块支持通过组合 JUnit 或 TestNG 来进行单元测试和集成测试 。它提供了连续的加载 ApplicationContext 并且 缓存这些上下文。它还提供了 mock object(模仿对象),您可以使用隔离测试你的代码。 2.2.2 AOP and Instrumentation 面向切面编程及 Instrumentation 2.2.3 Messaging 消息 2.2.4 Data Access/Integration 数据访问/集成 2.2.5 Web 2.2.6 Test Spring Framework 4.x Reference Documentation 中文翻译 142.2. 模块 Spring Framework 4.x Reference Documentation 中文翻译 152.2. 模块 前面的构建模块描述在很多的情况下使 Spring 是一个合理的选择,从资源受限的嵌入式程序到成熟的企业应用程序都可以使 用 Spring 事务管理功能和 web 框架集成。 Figure 2.2. Typical full-fledged Spring web application Spring 声明式事务管理特性使 Web 应用程序拥有完全的事务,就像你使用 EJB 容器管理的事务。所有的自定义业务逻辑可 以用简单的 POJO 实现,用 Spring 的 IoC 容器进行管理。额外的服务包括发送电子邮件和验证,是独立的网络层的支持, 它可以让你选择在何处执行验证规则。Spring 的 ORM 支持集成 JPA,Hibernate,JDO;例如,当使用 Hibernate,您可以 继续使用现有的映射文件和 标准的 Hibernate 的 SessionFactory 配置。表单控制器将 Web 层和领域模型无缝集成,消除 ActionForms 或其他类用于变换 HTTP 参数成为您的域模型值的需要。 Figure 2.3. Spring middle-tier using a third-party web framework 2.3 Usage scenarios 使用场景 Spring Framework 4.x Reference Documentation 中文翻译 162.3. 使用场景 有时,不允许你完全切换到一个不同的框架。Spring Framework 不强制使用它,它不是一个全有或全无的解决方案。现有的 前端 Struts, Tapestry, JSF 或其他 UI 框架,可以集成一个基于 Spring 中间件,它允许你使用 Spring 事务的功能。你只需要 将业务逻辑连接使用 ApplicationContext 和使用WebApplicationContext 集成到你的 web 层。 Figure 2.4. Remoting usage scenario Spring Framework 4.x Reference Documentation 中文翻译 172.3. 使用场景 当你需要通过 web 服务访问现有代码时,可以使用 Spring 的 Hessian-, Burlap-, Rmi- 或 JaxRpcProxyFactory 类。启用远程 访问现有的应用程序并不难。 Figure 2.5. EJBs - Wrapping existing POJOs Spring Framework 4.x Reference Documentation 中文翻译 182.3. 使用场景 Spring Framework 也提供了 Enterprise JavaBeans 访问和抽象层 使你能重用现有的 POJOs,并且在需要声明安全的时候打 包他们成为无状态的 bean 用于可伸缩,安全的 web 应用里。 依赖管理和依赖注入是不同的概念。为了让 Spring 的这些不错的功能运用到运用程序中(比如依赖注入),你需要收集所有 的需要的库(JAR文件),并且在编译、运行的时候将它们放到你的类路径中。这些依赖不是虚拟组件的注入,而是物理的 资源在文件系统中(通常)。依赖管理过程包括定位这些资源,存储它们并添加它们到类路径。依赖可以是直接(如我的应 用程序运行时依赖于 Spring ),或者是间接(如我的应用程序依赖 commons-dbcp ,而 commons-dbcp 又依赖于 commons-pool)。间接的依赖也被称为 “transitive (传递)”,它是最难识别和管理的依赖。 如果你将使用 Spring,你需要复制哪些包含你需要的 Spring 功能的 jar包。为了使这个过程更加简单,Spring 被打包为一组 模块,这些模块尽可能多的分开依赖关系。例如,如果不想写一个 web 应用程序,你就不需要引入 Spring-web 模块。为了 在本指南中标记 Spring 库模块我们使用了速记命名约定 spring- 或者 spring-.jar ,其中*代表模块的短名(比如 spring- core,spring-webmvc, spring-jms 等)。实际的jar 文件的名字,通常是用模块名字和版本号级联(如spring-core- 4.1.4.BUILD-SNAPSHOT.jar) 每个 Spring Framework 发行版本将会放到下面的位置: Maven Central (Maven 中央库),这是 Maven 查询的默认库,而不需要任何特殊的配置就能使用。许多常用的 Spring 的依赖库也存在与Maven Central ,并且 Spring 社区的很大一部分都使用 Maven 进行依赖管理,所以这是最方 便他们的。jar 命名格式是 spring-*-.jar , Maven groupId 是 org.springframework 公共 Maven 仓库还拥有 Spring 专有的库。除了最终的 GA 版本,这个库还保存开发的快照和里程碑。JAR 文件的名字 是和 Maven Central 相同的形式,所以这是让 Spring 的开发版本使用其它部署在 Maven Central 库的一个有用的地方。 该库还包含一个用于发布的 zip 文件包含所有Spring jar,方便下载。 所以首先,你要决定用什么方式管理你的依赖,通常建议你使用自动系统像 Maven, Gradle 或 Ivy, 当你也可以下载 jar 下面是 Spring 中的组件列表。更多描述,详见2.2. Modules (模块) Table 2.1. Spring Framework Artifacts GroupId ArtifactId Description org.springframework spring-aop Proxy-based AOP support org.springframework spring-aspects AspectJ based aspects org.springframework spring-beans Beans support, including Groovy org.springframework spring-context Application context runtime, including scheduling and remoting abstractions org.springframework spring-context- support Support classes for integrating common third-party libraries into a Spring application context org.springframework spring-core Core utilities, used by many other Spring modules org.springframework spring-expression Spring Expression Language (SpEL) org.springframework spring-instrument Instrumentation agent for JVM bootstrapping spring- 2.3.1 Dependency Management and Naming Conventions 依赖关系管理和命名约定 Spring Framework 4.x Reference Documentation 中文翻译 192.3. 使用场景 org.springframework instrument- tomcat Instrumentation agent for Tomcat org.springframework spring-jdbc JDBC support package, including DataSource setup and JDBC access support org.springframework spring-jms JMS support package, including helper classes to send and receive JMS messages org.springframework spring-messaging Support for messaging architectures and protocols org.springframework spring-orm Object/Relational Mapping, including JPA and Hibernate support org.springframework spring-oxm Object/XML Mapping org.springframework spring-test Support for unit testing and integration testing Spring components org.springframework spring-tx Transaction infrastructure, including DAO support and JCA integration org.springframework spring-web Web support packages, including client and web remoting org.springframework spring-webmvc REST Web Services and model-view-controller implementation for web applications org.springframework spring-webmvc- portlet MVC implementation to be used in a Portlet environment org.springframework spring-websocket WebSocket and SockJS implementations, including STOMP support 虽然 Spring 提供了集成在一个大范围的企业和其他外部工具的支持,它故意保持其强制性依赖关系降到最低:在简单的用例 里,你无需查找并下载(甚至自动)一大批 jar 库来使用 Spring 。基本的依赖注入只有一个外部强制性的依赖,这是用来做 日志的(见下面更详细地描述日志选项)。 接下来我们将一步步展示如果配置依赖 Spring 的程序,首先用 Maven 然后用 Gradle 和最后用 Ivy。在所有的情况下,如果 有不清楚的地方,查看的依赖性管理系统的文档,或看一些示例代码。Spring 本身是使用 Gradle 来管理依赖的,我们的很 多示例也是使用 Gradle 或 Maven。 译者注:有关 Gradle 的使用,可以参见笔者的另外一部作品《Gradle 2 用户指南》 如果您使用的是 Maven 的依赖管理你甚至不需要明确提供日志依赖。例如,要创建一个应用程序的上下文和使用依赖注入来 配置应用程序,你的Maven 依赖将看起来像这样: org.springframework spring-context 4.1.4.RELEASE Spring Dependencies and Depending on Spring Maven Dependency Management Spring Framework 4.x Reference Documentation 中文翻译 202.3. 使用场景 runtime 就是它。注意 scope 可声明为 runtime (运行时)如果你不需要编译 Spring 的API,这通常是基本的依赖注入使用的案例。 以上与 Maven Central 存储库工程实例。使用 Spring Maven 存储库(如里程碑或开发者快照),你需要在你的 Maven 配置 指定的存储位置。如下: io.spring.repo.maven.release http://repo.spring.io/release/ false 里程碑: io.spring.repo.maven.milestone http://repo.spring.io/milestone/ false 以及快照: io.spring.repo.maven.snapshot http://repo.spring.io/snapshot/ true 有可能不小心使用不同版本的 Spring JAR 在使用 Maven 时。例如,你可能发现一个第三方的库,或另一 Spring 的项目, 拉取了一个在传递依赖较早的发布包。如果你自己忘记了显式声明一个直接依赖,各种意想不到的问题出现。 为了克服这些问题,Maven 支持 "bill of materials" (BOM) 的依赖的概念。你可以在你的 dependencyManagement 部分引入 spring-framework-bom 来确保所有 spring依赖(包括直接和传递的)是同一版本。 org.springframework spring-framework-bom 4.1.4.RELEASE pom import 使用 BOM 后,当依赖 Spring Framework 组件后,无需指定 属性 Maven "Bill Of Materials" Dependency Spring Framework 4.x Reference Documentation 中文翻译 212.3. 使用场景 org.springframework spring-context org.springframework spring-web 用 Gradle 来使用 Spring ,在 repositories 中填入适当的 URL : repositories { mavenCentral() // and optionally... maven { url "http://repo.spring.io/release" } } 可以适当修改 URL 从 /release 到 /milestone 或 /snapshot 。库一旦配置,就能声明 Gradle 依赖: dependencies { compile("org.springframework:spring-context:4.1.4.RELEASE") testCompile("org.springframework:spring-test:4.1.4.RELEASE") } 如果你更喜欢用Ivy管理依赖也有类似的配置选项。 配置 Ivy ,将指向 Spring 的库 添加下面的 resolver(解析器)到你ivysettings.xml: 可以适当修改 root URL 从 /release 到 /milestone 或 /snapshot 。 一旦配置,就能添加依赖,举例 (在 ivy.xml): 虽然使用构建系统,支持依赖管理是推荐的方式获得了 Spring Framework,,它仍然是可下载分发的 zip 文件。 分发的 zip 文件是发布到 Spring Maven Repository (这是为了我们的便利,在下载这些文件的时候你不需要 Maven 或者其 他的构建系统)。 Gradle Dependency Management Ivy Dependency Management Distribution Zip Files 分发的 zip 文件 Spring Framework 4.x Reference Documentation 中文翻译 222.3. 使用场景 下载一个 Zip,在web 浏览器打开 http://repo.spring.io/release/org/springframework/spring ,选择适当的文件夹的版本。下 载完毕文件结尾是 -dist.zip,例如,spring-framework-4.1.4.BUILD-SNAPSHOT-RELEASE-dist.zip 。分发也支持发布里程 碑和快照。 对于 Spring 日志是非常重要的依赖,因为:a)它是唯一的外部强制性的依赖;b)每个人都喜欢从他们使用的工具看到一些 输出;c)Spring 结合很多其他工具都选择了日志依赖。应用开发者的一个目标就是往往是有统一的日志配置在一个中心位 置为了整个应用程序,包括所有的外部元件。这就更加困难,因为它可能已经有太多选择的日志框架。 在 Spring 强制性的日志依赖 是 Jakarta Commons Logging API(JCL)。我们编译 JCL,我们也使得 JCL Log 对象对 Spring Framework 的扩展类可见。所有版本的 Spring 使用同样的日志库,这对于用户来说是很重要的:迁移就会变得容易 向后兼容性,即使扩展 Spring的应用程序。我们这样做是为了是 Spring 的模块之一明确依赖 commons-logging (JCL的典型 实现),然后是的其他的所有模块在编译的时候都依赖它。如果你使用 Maven 为例,在你想拿起依赖 commons-logging ,这 个是来自 Spring 的并且明确来自中心模块 spring-core。 关于 commons-logging 的好处是你不需要任何东西就能让你的应用程序程序跑起来。它运行时有一个发现算法,该算法在类 路径的所有地方寻找其他的日志框架并且使用它认为适合的(或者你可以告诉它你需要的是哪一个)。如果没有其他的用 途,你可以从JDK(Java.util.logging 或者JUL 的简称)获得日志。在大多数情况下,你可以在控制台查看你的Spring 应用程 序工作和日志,并且这是很重要的。 不幸的,在 commons-logging 里运行时发现算法,方便最终用户,是有问题的。如果我们能够时光倒流,现在从新开始 Spring 项目并且他使用了不同的日志依赖。第一个选择很可能是Simple Logging Facade for Java ( SLF4J),过去也曾被许 多其他工具通过 Spring 使用在他们的应用程序。 基本上有两种方法可以关闭commons-logging: 1. 通过 spring-core 模块排除依赖(因为它是唯一的显示依赖于 commons-logging 的模块)。 2. 依赖特殊的 commons-logging 依赖,用空的jar(更多的细节可以在SLF4J FAQ中找到)替换掉库。 排除 commons-logging,添加以下的内容到 dependencyManagement 部分: org.springframework spring-core 4.1.4.RELEASE commons-logging commons-logging 现在,这个应用程序可以打破,因为在类路径上没有实现 JCL API,因此要修复它就必须提供有一个新的。在下一节我们将 向你展示如何提供另一种实现 JCL,使用 SLF4J 作为例子的另一种实现。 SLF4J 是一个更加简洁的依赖,在运行时相对于 commons-logging 更加的有效因为它使用编译时绑定来代替运行时发现其 他日志框架的集成。这也意味着,你不得不更加明确你想在运行时发生什么,并相应的声明它或者配置它。SLF4J 提供绑定 很多的常见日志框架,因此你可以选择一个你已经使用的,并且绑定到配置和管理。 2.3.2 Logging 日志 Not Using Commons Logging 不使用 Commons Logging Using SLF4J 使用 SLF4J Spring Framework 4.x Reference Documentation 中文翻译 232.3. 使用场景 SLF4J 提供了绑定很多的常见日志框架,包括 JCL,它也做了反向工作:是其他日志框架和它自己之间的桥梁。因此在 Spring 中使用 SLF4J 时,你需要使用 SLF4J-JCL 桥接替换掉 commons-logging 的依赖。一旦你这么做了,Spring 调用日 志就会调用 SLF4J API,因此如果在你的应用程序中的其他库使用这个API,那么你就需要有个地方配置和管理日志。 一个常见的选择就是桥接 Spring 和 SLF4J,提供显示的绑定 SLF4J 到Log4J 上。你需要支持 4 个的依赖(排除现有的 commons-logging):桥接,SLF4J API,绑定 Log4J 和 Log4J 实现自身。在 Maven 中你可以这样做: org.springframework spring-core 4.1.4.RELEASE commons-logging commons-logging org.slf4j jcl-over-slf4j 1.5.8 org.slf4j slf4j-api 1.5.8 org.slf4j slf4j-log4j12 1.5.8 log4j log4j 1.2.14 这似乎是一个很大的依赖性,其仅仅是为了得到一些日志文件。那就这样吧,但是它是可选的,它在关于类加载器的问题上 应该比 commons-logging 表现的更加的好,值得注意的是,如果你在一个严格的容器中像OSGi 平台。据说也有一个性能优 势应为绑定是在编译时而不是在运行时。 SLF4J 是用户中一个常见的选择,使用它可以更少的步骤和产生更少的依赖,直接绑定 Logback。这消除了多余的绑定步 骤,因为 Logback 直接实现了 SLF4J,因此你只需要依赖两个库而不是4个(jcl-over-slf4j 和 logback)。如果你这样做,你 可能还需要从其他外部依赖(不是 Spring)排除 slf4j-api 依赖,因为在类路径中你只需要一个版本的API。 许多人使用 Log4j 作为日志框架,用于配置和管理的目的。它是有效的和完善的,事实上这也是我们在运行时使用的,当我 们构架和测试 Spring 时。Spring 也提供一些配置和初始化 Log4j 的工具,因此在某些模块上它有一个可选的编译时依赖在 Log4j。 为了使 Log4j 工作在默认的 JCL 依赖下(commons-logging),所有你需要做的事就是把 Log4j 放到类路径下,为它提供配 置文件(log4j.properties 或者 log4j.xml 在类路径的根目录下)。因此对于Maven 用户这就是你的依赖声明: org.springframework spring-core 4.1.4.RELEASE Using Log4J 使用 Log4J Spring Framework 4.x Reference Documentation 中文翻译 242.3. 使用场景 log4j log4j 1.2.14 下面是一个 log4j.properties 的实例,用于将日志打印到控制台: log4j.rootCategory=INFO, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n log4j.category.org.springframework.beans.factory=DEBUG 很多的人在提供 JCL 实现的容器下运行他们的 Spring 应用程序。IBM Websphere Application Server (WAS)为例。这样往往 会导致问题,遗憾的是没有一个一劳永逸的解决方案;简单的包含 commons-logging 在大多数情况下是不够的。 要清楚这一点:问题报告通常不是 JCL 本身,或者 commons-logging:相反,他们是绑定 commons-logging 到其他的框架 (通常是 Log4j )。这可能会失败,因为commons-logging改变了路径,当他们运行时发现在一些容器中找到了老版本 (1.0)并且现在大多数人使用的现代版本(1.1)。Spring 不使用 JCL API 任何不常见的模块,所以没有什么问题出现,但是 很快 Spring 或者你的应用程序视图做一些日志时,你会发现绑定的 Log4j 不工作了。 在这种情况下,WAS 最容易的是转化类加载器的层次结构(IBM 称之为“parent last”),使应用程序控制 JCL 的依赖关系, 而不是容器。该选项不是总是开放的,但是有很多其他的建议在公共领域的替代方法,你的里程可能取决于确切的版本和特 定的容器。 Runtime Containers with Native JCL Spring Framework 4.x Reference Documentation 中文翻译 252.3. 使用场景 Spring Framework 4.x Reference Documentation 中文翻译 26II. Spring Framework 4.x 新特性 Spring 框架第一个版本发布于 2004 年,自发布以来已历经三个主要版本更新: Spring 2.0 提供了 XML 命名空间和 AspectJ 支持;Spring 2.5 增加了注释驱动(annotation-driven)的配置支持; Spring 3.0增加了对 Java 5+ 版本的支持和 @Configuration 模型。 Spring 4.0 是最新的主要版本,并且首次完全支持 Java 8 的特性。你仍然可以使用老版本的 Java,但是最低版本的要求已 经提高到 Java SE 6。我们也借主要版本更新的机会删除了许多过时的类和方法。 你可以在Spring Framework GitHub Wiki上查看 升级 Spring 4.0 的迁移指南。 3. New Features and Enhancements in Spring Framework 4.0 在 Spring 4.0 新功能和增强 Spring Framework 4.x Reference Documentation 中文翻译 273. Spring Framework 4.0中的新功能和增强功能 新的 spring.io 网站提供了一整个系列的 "入门指南" 帮助你学习 Spring。你可以本文档的 1. Getting Started with Spring 一节 阅读更多的入门指南。新网站还提供了Spring 之下其他额外项目的一个全面的概述。 如果你是一个 Maven 用户,你可能会对 BOM 这个有用的 POM 文件感兴趣, 这个文件已经与每个 Spring 的发布版发布。 3.1 Improved Getting Started Experience 改进的入门体验 Spring Framework 4.x Reference Documentation 中文翻译 283.1. Improved Getting Started Experience 所有过时的包和许多过时的类和方法已经从Spring4中移除。如果你从之前的发布版升级Spring,你需要保证已经修复了所有 使用过时的API方法。 查看完整的变化: API差异报告。 请注意,所有可选的第三方依赖都已经升级到了最低2010/2011(例如Spring4 通常只支持 2010 年的最新或者现在的最新发布 版本):尤其是 Hibernate 3.6+、EhCache 2.1+、Quartz 1.8+、Groovy 1.8+、Joda-Time 2.0+。但是有一个例外,Spring4依 赖最近的Hibernate Validator 4.3+,现在对Jackson的支持集中在2.0+版本 (Spring3.2支持的Jackson 1.8/1.9,现在已经过 时)。 3.2 Removed Deprecated Packages and Methods 移除不 推荐的包和方法 Spring Framework 4.x Reference Documentation 中文翻译 293.2. Removed Deprecated Packages and Methods Spring4 支持 Java8 的一些特性。你可以在 Spring 的回调接口中使用 lambda 表达式 和 方法引用。支持 java.time (JSR- 310)的值类型和一些改进过的注解,例如 @Repeatable 。你还可以使用 Java8 的参数名称发现机制(基于 -parameters 编译 器标志)。 Spring 仍然兼容老版本的 Java 和 JDK:Java SE 6(具体来说,支持JDK6 update 18 )以上版本,我们建议新的基于 Spring4 的项目使用Java7或Java8。 3.3 Java 8 (as well as 6 and 7) Spring Framework 4.x Reference Documentation 中文翻译 303.3. Java 8 (as well as 6 and 7) Java EE 6 或以上版本是 Spring4 的底线,与 JPA2.0 和 Servlet3.0规范有着特殊的意义。为了保持与 Google App Engine 和 旧的应用程序服务器兼容,Spring4 可以部署在 Servlet2.5 运行环境。但是我们强烈的建议您在 Spring 测试和模拟测试的开发 环境中使用 Servlet3.0+。 如果你是WebSphere 7的用户,一定要安装JPA2.0功能包。在WebLogic 10.3.4或更高版本,安装附带的JPA2.0补丁。这样 就可以将这两种服务器变成Spring4兼容的部署环境。 从长远的观点来看,Spring4.0 现在支持 Java EE 7 级别的适用性规范:尤其是 JMS 2.0, JTA 1.2, JPA 2.1, Bean Validation 1.1 和JSR-236 并发工具类。像往常一样,支持的重点是独立的使用这些规范。例如在 Tomcat 或者独立环境中。但是,当 把 Spring 应用部署到 Java EE 7 服务器时它同样适用。 注意,Hibernate 4.3 是 JPA 2.1 的提供者,因此它只支持 Spring4。同样适用用于作为 Bean Validation 1.1 提供者的 Hibernate Validator 5.0。这两个都不支持 Spring3.2。 3.4 Java EE 6 and 7 Spring Framework 4.x Reference Documentation 中文翻译 313.4. Java EE 6 and 7 Spring4.0 支持使用 Groovy DSL 来进行外部的 bean 定义配置。这在概念上类似于使用 XML 的 bean 定义,但是支持更简 洁的语法。使用Groovy 还允许您轻松地将 bean 定义直接嵌入到引导代码中。例如: def reader = new GroovyBeanDefinitionReader(myApplicationContext) reader.beans { dataSource(BasicDataSource) { driverClassName = "org.hsqldb.jdbcDriver" url = "jdbc:hsqldb:mem:grailsDB" username = "sa" password = "" settings = [mynew:"setting"] } sessionFactory(SessionFactory) { dataSource = dataSource } myService(MyService) { nestedBean = { AnotherBean bean -> dataSource = dataSource } } } 有关更多信息,请参阅 GroovyBeanDefinitionReader javadocs 3.5 Groovy Bean Definition DSL Spring Framework 4.x Reference Documentation 中文翻译 323.5. Groovy Bean Definition DSL 有几种对核心容器的常规改进: Spring 现在注入 Bean 的时候把 泛型类型当成一种形式的限定符。例如:如果你使用S pring Data Repository 你可以 方便的插入特定的实现: @Autowired Repository customerRepository 。 如果你使用 Spring 的元注解支持,你现在可以开发自定义注解来公开源注解的特定属性。 当自动装配到lists和arrays时,Beans 现* 在可以被 排序 了。支持 @Order 注解和 Ordered 接口两种方式。 @Lazy 注解现 在可以用在注入点以及 @Bean 定义上。 引入 @Description 注解,开发人员可以使用基于Java 方式的配置。 根据条件筛选 Beans的广义模型通过 @Conditional 注解加入。这和 @Profile 支持的类似,但是允许以编程式开发用户定 义的策略。 基于CGLIB的代理类不在需要默认的构造方法。这个支持是由 objenesis库提供。这个库重新打包到 Spring 框架中,作 为Spring框架的一部分发布。通过这个策略,针对代理实例被调用没有构造可言了。 框架现在支持管理时区。例如 LocaleContext 。 3.6 Core Container Improvements 核心容器改进 Spring Framework 4.x Reference Documentation 中文翻译 333.6. Core Container Improvements 现在仍然可以部署到 Servlet 2.5 服务器,但是 Spring4.0 现在主要集中在 Servlet 3.0+ 环境。如果你使用 Spring MVC 测试 框架,你需要将 Servlet 3.0 兼容的 JAR 包放到 测试的 classpath 下。 除了稍后会提到的 WebSocket 支持外,下面的常规改进已经加入到Spring 的 Web 模块: 你可以在Spring MVC应用中使用新的 @RestController 注解,不在需要给 @RequestMapping 的方法添加 @ResponseBody 注 解。 AsyncRestTemplate 类已被添加进来,当开发 REST 客户端时,允许非阻塞异步支持。 当开发 Spring MVC 应用时,Spring现在提供了全面的时区支持 。 3.7 General Web Improvements 常规Web改进 Spring Framework 4.x Reference Documentation 中文翻译 343.7. General Web Improvements 一个新的 spring-websocket 模块提供了全面的基于 WebSocket 和在Web 应用的客户端和服务器之间双向通信的支持。它和 Java WebSocket API JSR-356 兼容,此外还提供了当浏览器不支持 WebSocket 协议时 (如 Internet Explorer < 10)的基于 SockJS 的备用选项(如 WebSocket emulation)。 一个新的 spring-messaging 模块添加了支持 STOMP 作为 WebSocket 子协议用于在应用中使用注解编程模型路由和处理从 WebSocket 客户端发送的 STOMP 消息。由于 @Controller 现在可以同时包含 @RequestMapping 和 @MessageMapping 方法用于 处理 HTTP 请求和来自 WebSocket 连接客户端发送的消息。新的 spring-messaging 模块还包含了来自以前 Spring 集成项目 的关键抽象,例如 Message 、 MessageChannel 、 MessageHandler 和其他作为基于消息传递的应用程序的基础。 欲知详情以及较全面的介绍,请参见Chapter 20, WebSocket 支持一节。 3.8 WebSocket, SockJS, and STOMP Messaging Spring Framework 4.x Reference Documentation 中文翻译 353.8. WebSocket, SockJS, and STOMP Messaging 除了精简 spring-test 模块中过时的代码外,Spring 4 还引入了几个用于单元测试和集成测试的新功能。 几乎 spring-test 模块中所有的注解(例 如: @ContextConfiguration 、 @WebAppConfiguration 、 @ContextHierarchy 、 @ActiveProfiles 等等)现在可以用作元注解 来创建自定义的 composed annotations 并且可以减少测试套件的配置。 现在可以以编程方式解决Bean定义配置文件的激活。只需要实现一个自定义的ActiveProfilesResolver,并且通过 @ActiveProfiles的resolver属性注册。 新的 SocketUtils 类被引入到了 spring-core 模块。这个类可以使你能够扫描本地主机的空闲的 TCP 和 UDP 服务端 口。这个功能不是专门用在测试的,但是可以证明在你使用 Socket 写集成测试的时候非常有用。例如测试内存中启动 的SMTP服务器,FTP服务器,Servlet容器等。 从 Spring 4.0 开始, org.springframework.mock.web 包中的一套mock是基于Servlet 3.0 API。此外,一些Servlet API mocks(例如: MockHttpServletRequest 、 MockServletContext 等等)已经有一些小的改进更新,提高了可配置性。 3.9 Testing Improvements 测试改进 Spring Framework 4.x Reference Documentation 中文翻译 363.9. Testing Improvements Spring Framework 4.x Reference Documentation 中文翻译 374. Spring Framework 4.1中的新功能和增强功能 Spring 4.1 引入了一个更简单的基础架构,使用 @JmsListener 注解bean 方法来注册 JMS 监听端点。XML 命名空间已经通过 增强来支持这种新的方式( jms:annotation-driven ),它也可以完全通过Java配置( @EnableJms , JmsListenerContainerFactory )来配置架构。也可以使用 JmsListenerConfigurer 注解来注册监听端点。 Spring 4.1 还调整了 JMS 的支持,使得你可以从 spring-messaging 在 Spring4.0 引入的抽象获益,即: 消息监听端点可以有更为灵活的签名,并且可以从标准的消息注解获益,例如 @Payload 、 @Header 、 @Headers 和 @ SendTo 注解。另外,也可以使用一个标准的消息,以代替 javax.jms.Message 作为方法参数。 一个新的可用 JmsMessageOperations 接口和允许操作使用 Message 抽象的 JmsTemplate 。 最后,Spring 4.1提供了其他各种各样的改进: JmsTemplate中的同步请求-答复操作支持 监听器的优先权可以指定每个 元素 消息侦听器容器恢复选项可以通过使用 BackOff 实现进行配置 JMS 2.0消费者支持共享 4.1 JMS 改进 Spring Framework 4.x Reference Documentation 中文翻译 384.1. JMS Improvements Spring 4.1 支持JCache (JSR-107)注解使用Spring的现有缓存配置和基础结构的抽象;使用标准注解不需要任何更改。 Spring 4.1也大大提高了自己的缓存抽象: 缓存可以在运行时使用 CacheResolver 解决。因此使用 value 参数定义的缓存名称不在是强制性的。 更多的操作级自定义项:缓存解析器,缓存管理器,键值生成器 一个新的 @CacheConfig 类级别注解允许在类级别上共享常用配置,不需要启用任何缓存操作。 使用 CacheErrorHandler 更好的处理缓存方法的异常 Spring 4.1为了在 CacheInterface 添加一个新的 putIfAbsent 方法也做了重大的更改。 4.2 Caching 改进 Spring Framework 4.x Reference Documentation 中文翻译 394.2. Caching Improvements 现有的基于 ResourceHttpRequestHandler 的资源处理已经扩展了新的抽 象 ResourceResolver , ResourceTransformer 和 ResourceUrlProvider 。一些内置的实现提供了版本控制资源的 URL(有 效的 HTTP 缓存),定位 gzip 压缩的资源,产生 HTML5 AppCache清单,以及更多的支持。参见第17.16.7,“Serving of Resources(服务资源)”。 JDK 1.8 的 java.util.Optional 现在支持 @RequestParam , @RequestHeader 和 @MatrixVariable 控制器方法的参数。 ListenableFuture 支持作为返回值替代 DeferredResult 所在的底层服务(或者调用 AsyncRestTemplate )已经返 回 ListenableFuture 。 @ModelAttribute 方法现在依照相互依存关系的顺序调用。见SPR-6299。 Jackson的 @JsonView 被直接支撑在 @ResponseBody 和 ResponseEntity 控制器方法用于序列化不同的细节对于相同的 POJO(如摘要与细节页)。同时通过添加序列化视图类型作为模型属性的特殊键来支持基于视图的渲染。见Jackson Serialization View Support(Jackson序列化视图支持) Jackson 现在支持 JSONP ,见 Jackson JSONP Support 一个新的生命周期选项可用于在控制方法返回后,响应被写入之前拦截 @ResponseBody 和 ResponseEntity 方法。要充分 利用声明 @ControllerAdvice bean 实现 ResponseBodyAdvice 。为 @JsonView 和 JSONP 的内置支持利用这一优势。参见 第17.4.1,“使用HandlerInterceptor 拦截请求”。 有三个新的 HttpMessageConverter 选项: GSON - 比 Jackson 更轻量级的封装;已经被使用在 Spring Android Google Protocol Buffers - 高效和有效的企业内部跨业务的数据通信协议,但也可以用于浏览器的 JSON 和 XML 的 扩展 Jackson 基于 XML 序列化,现在通过 jackson-dataformat-xml 扩展得到了支持。如果 jackson-dataformat-xml 在 classpath, 默认情况下使用 @EnableWebMvc 或 ,这是,而不是JAXB2。 如 JSP 等视图现在可以通过名称参照控制器映射建立链接控制器。默认名称分配给每一个 @RequestMapping 。例 如 FooController 的方法与 handleFoo 被命名为“FC#handleFoo”。命名策略是可插拔的。另外,也可以通过其名称属性 明确命名的 @RequestMapping 。在Spring JSP标签库的新 mvcUrl 功能使这个简单的JSP页面中使用。参见第 17.7.2,“Building URIs to Controllers and methods from views” ResponseEntity 提供了一种 builder 风格的 API 来指导控制器向服务器端的响应的展示,例如,ResponseEntity.ok()。 RequestEntity 是一种新型的,提供了一个 builder 风格的 API 来引导客户端的 REST 响应 HTTP 请求的展示。 MVC 的 Java 配置和 XML 命名空间: 视图解析器现在可以配置包括内容协商的支持,请参见17.16.6“视图解析”。 视图控制器现在已经内置支持重定向和设置响应状态。应用程序可以使用它来配置重定向的URL,404 视图的响 应,发送“no content”的响应,等等。有些用例这里列出。 现在内置路径匹配的自定义。参见第17.16.9,“路径匹配”。 Groovy 的标记模板支持(基于Groovy的2.3)。见 GroovyMarkupConfigurer 和各自的 ViewResolver 和“视图”的实现。 4.3. Web 改进 Spring Framework 4.x Reference Documentation 中文翻译 404.3. Web Improvements SockJS(Java)客户端支持.查看 SockJsClient 和在相同包下的其他类. 发布新的应用上下文实践 SessionSubscribeEvent 和 SessionUnsubscribeEvent ,用于STOMP客户端的订阅和取消订阅. 新的"websocket"级别.查看Section 21.4.13, “WebSocket Scope”. @SendToUser 仅仅靠一个会话就可以命中,而不一定需要一个授权的用户. @MessageMapping 方法使用.来代替/作为目录分隔符。查看 SPR-11660.。 STOMP/WebSocket 监听消息的收集和记录。查看21.4.15, “Runtime Monitoring”.。 显著优化和改善在调试模式下依然保持日志的可读性和简洁性。 优化消息创建,包含对临时消息可变性的支持和避免自动消息ID和时间戳的创建。查看 MessageHeaderAccessor 的java文 档。 在WebSocket会话建立之后的1分钟没有任何活动,则关闭STOMP/WebSocket连接。 4.4 WebSocket STOMP Messaging 改进 Spring Framework 4.x Reference Documentation 中文翻译 414.4. WebSocket STOMP Messaging Improvements Groovy脚本现在能使用 ApplicationContext 配置,在TestContext框架中整合测试。the section called “Context configuration with Groovy scripts” 现在通过新的 TestTransaction 接口,使用编程化来开始结束测试管理事务。the section called “Programmatic transaction management” 现在SQL脚本的执行可以通过 Sql 和 SqlConfig 注解申明在每一个类和方法中。the section called “Executing SQL scripts” 测试属性值可以通过配置 @TestPropertySource 注解来自动覆盖系统和应用的属性值。the section called “Context configuration with test property sources”。 默认的 TestExecutionListeners 现在可以自动被发现。the section called “Automatic discovery of default TestExecutionListeners” 。 自定义的 TestExecutionListeners 现在可以通过默认的监听器自动合并。the section called “Merging TestExecutionListeners”。 在TestContext框架中的测试事务方面的文档已经通过更多解释和其他事例得到改善。the section called “Transaction management”。 MockServletContext 、 MockHttpServletRequest 和其他servlet接口mocks等诸多改善。 AssertThrows 重构后, Throwable 代替 Exception 。 Spring MVC测试中,使用JSONPath选项返回JSON格式可以使用JSON Assert来断言,非常像之前的XML和XMLUnit。 MockMvcBuilder 现在可以在 MockMvcConfigurer 的帮助下创建。 MockMvcConfigurer 的加入使得Spring Security的设置更加 简单,同时使用于任何第三方的普通封装设置或则仅仅在本项目中。 MockRestServiceServer 现在支持 AsyncRestTemplate 作为客户端测试。 发布新的应用上下文实践 SessionSubscribeEvent 和 SessionUnsubscribeEvent ,用于STOMP客户端的订阅和取消订阅. 新的"websocket"级别.查看[Section 21.4.13, “WebSocket Scope”.](http://docs.spring.io/spring/docs/current/spring- framework- 4.5 测试 改进 Spring Framework 4.x Reference Documentation 中文翻译 424.5. Testing Improvements 该部分的参考文档涵盖了Spring Framework中所有绝对不可或缺的技术。 这其中最重要的部分就是Spring Framework中的控制反转(IoC)容器。Spring Framework中IoC容器是紧随着Spring中面向 切面编程(AOP)技术的全面应用的来完整实现的。Spring Framework有它自己的一套AOP框架,这套框架从概念上很容易 理解,而且成功解决了Java企业级应用中AOP需求80%的核心要素。 同样Spring与AspectJ(目前从功能上来说是最丰富,而且也无疑是Java企业领域最成熟的AOP实现)的集成也涵盖在内。 最后,Spring团队相当推崇采用测试驱动开发(TDD)的方法来进行软件开发,所以Spring对于集成测试的支持也被涵盖在内 (与单元测试的最佳实践一起)。Spring团队发现对于IoC的正确使用使得单元测试和集成测试都变得简单了(如类中使用的 setter方法和合适的构造方法使得它们在测试中更加方便地连接到一起,而不用设置服务定位注册器等)...专门致力于测试的 那一章节也会很有希望地使你认同这一观点。 Chapter 5, IoC容器 Chapter 6, 资源 Chapter 7, 验证,数据绑定和类型转换 Chapter 8, Spring表达式语言(SpEL) Chapter 9, Spring中的面向切面编程 Chapter 10, Spring AOP APIs Chapter 11, 测试 Part III. 核心技术 Spring Framework 4.x Reference Documentation 中文翻译 43III. Core Technologies Spring Framework 4.x Reference Documentation 中文翻译 445. The IoC container Spring Framework 4.x Reference Documentation 中文翻译 455.1. Introduction to the Spring IoC container and beans Spring Framework 4.x Reference Documentation 中文翻译 465.2. Container overview Spring Framework 4.x Reference Documentation 中文翻译 475.3. Bean overview Spring Framework 4.x Reference Documentation 中文翻译 485.4. Dependencies Spring Framework 4.x Reference Documentation 中文翻译 495.5. Bean scopes Spring Framework 4.x Reference Documentation 中文翻译 505.6. Customizing the nature of a bean Spring Framework 4.x Reference Documentation 中文翻译 515.7. Bean definition inheritance Spring Framework 4.x Reference Documentation 中文翻译 525.8. Container Extension Points Spring Framework 4.x Reference Documentation 中文翻译 535.10. Classpath scanning and managed components Spring Framework 4.x Reference Documentation 中文翻译 545.11. Using JSR 330 Standard Annotations Spring Framework 4.x Reference Documentation 中文翻译 555.12. Java-based container configuration Spring Framework 4.x Reference Documentation 中文翻译 565.13. Environment abstraction Spring Framework 4.x Reference Documentation 中文翻译 575.14. Registering a LoadTimeWeaver Spring Framework 4.x Reference Documentation 中文翻译 585.15. Additional Capabilities of the ApplicationContext Spring Framework 4.x Reference Documentation 中文翻译 595.16. The BeanFactory Spring Framework 4.x Reference Documentation 中文翻译 606. Resources Spring Framework 4.x Reference Documentation 中文翻译 616.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 626.2. The Resource interface Spring Framework 4.x Reference Documentation 中文翻译 636.3. Built-in Resource implementations Spring Framework 4.x Reference Documentation 中文翻译 646.4. The ResourceLoader Spring Framework 4.x Reference Documentation 中文翻译 656.5. The ResourceLoaderAware interface Spring Framework 4.x Reference Documentation 中文翻译 666.6. Resources as dependencies Spring Framework 4.x Reference Documentation 中文翻译 676.7. Application contexts and Resource paths Spring Framework 4.x Reference Documentation 中文翻译 687. Validation, Data Binding, and Type Conversion Spring Framework 4.x Reference Documentation 中文翻译 697.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 707.2. Validation using Spring’s Validator interface Spring Framework 4.x Reference Documentation 中文翻译 717.3. Resolving codes to error messages Spring Framework 4.x Reference Documentation 中文翻译 727.4. Bean manipulation and the BeanWrapper Spring Framework 4.x Reference Documentation 中文翻译 737.5. Spring Type Conversion Spring Framework 4.x Reference Documentation 中文翻译 747.6. Spring Field Formatting Spring Framework 4.x Reference Documentation 中文翻译 757.7. Configuring a global date & time format Spring Framework 4.x Reference Documentation 中文翻译 767.8. Spring Validation Spring Framework 4.x Reference Documentation 中文翻译 778. Spring Expression Language-SpEL Spring Framework 4.x Reference Documentation 中文翻译 788.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 798.2. Feature Overview Spring Framework 4.x Reference Documentation 中文翻译 808.3. Expression Evaluation using Spring’s Expression Interface Spring Framework 4.x Reference Documentation 中文翻译 818.4. Expression support for defining bean definitions Spring Framework 4.x Reference Documentation 中文翻译 828.5. Language Reference Spring Framework 4.x Reference Documentation 中文翻译 838.6. Classes used in the examples Spring Framework 4.x Reference Documentation 中文翻译 849. Aspect Oriented Programming with Spring Aspect-Oriented Programming (面相切面编程 AOP) 用另外的一种编程架构的思考来补充 Object-Oriented Programming (面 相对象编程OOP)。OOP 主要的模块单元是 class (类),而 AOP 是 aspect(切面)。切面使得诸如事务管理等跨越多个类型 和对象的关注点模块化。(这样的关注点在 AOP 的字眼里往往被称为 crosscutting (横切关注点)) AOP 是 Spring 里面的主要的组件。虽然 Spring IoC 容器没有依赖 AOP,意味着你不想用的时候也无需使用 AOP,但 AOP 提供一个非常有用的中间件解决方案来作为 Spring IoC 的补充。 Spring 2.0 AOP Spring 2.0 引入了一种更加简单并且更强大的方式来自定义切面,用户可以选择使用 schema-based(基于模式)的方式或 者使用 @AspectJ 注解样式。这两种风格都完全支持 Advice(通知)类型和 AspectJ 的切入点语言,虽然实际上仍然使用 Spring AOP 进行 weaving (织入)。 本章主要讨论 Spring 2.0 对基于模式和基于 @AspectJ 的 AOP 支持。 Spring 2.0 完全保留了对 Spring 1.2 的向下兼容性, 下一章 10. Spring AOP APIs 将讨论 Spring 1.2 API 所提供的底层的 AOP 支持。 Spring中所使用的AOP: 提供声明式企业服务,特别是为了替代 EJB 声明式服务。最重要的服务是 declarative transaction management(声明 性事务管理), 这个服务建立在Spring的抽象事务管理(transaction abstraction)之上。 允许用户实现自定义的切面,用 AOP 来完善 OOP 的使用。 如果你只打算使用通用的声明式服务或者预先打包的声明式中间件服务,例如 pooling(缓冲池),你可以不直接使用 AOP ,可以忽略本章大部分内容 首先让我们从定义一些重要的 AOP 概念开始。这些术语不是 Spring 特有的。 不幸的是,Spring 术语并不是特别的直观;如 果 Spring 使用自己的术语,将会变得更加令人困惑。 Aspect(切面): 一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是 企业级 Java 应用中一个关于横 切关注点的很好的例子。 在 Spring AOP 中,切面可以使用通用类( schema-based基于模式的风格) 或者在普通类中 以 @Aspect 注解(@AspectJ 注解样式)来实现。 Join point (连接点): 在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。 在 Spring AOP 中,一个连接点 总是 代表一个方法的执行。 Advice(通知): 在切面的某个特定的 join point(连接点)上执行的动作。通知有各种类型,其中包 括“around”、“before”和“after”等通知。 通知的类型将在后面部分进行讨论。许多 AOP 框架,包括 Spring,都是以拦截 器做通知模型,并维护一个以连接点为中心的拦截器链。 Pointcut(切入点): 匹配 join point(连接点)的断言。通知和一个切入点表达式关联,并在满足这个切入点的连接点 上运行(例如,当执行某个特定名称的方法时)。 切入点表达式如何和连接点匹配是 AOP 的核心:Spring 默认使用 AspectJ 切入点语法。 Introduction(引入): 声明额外的方法或者某个类型的字段。 Spring 允许引入新的接口(以及一个对应的实现)到任 何被 advise(通知)的对象。 例如,你可以使用一个引入来使 bean 实现 IsModified 接口,以便简化缓存机制。(在 AspectJ 社区 ,Introduction也被称为 inter-type declaration(内部类型声明)) Target object(目标对象): 被一个或者多个 aspect(切面)所advise(通知)的对象。也有人把它叫做 advised (被 通知) 对象。 既然 Spring AOP 是通过运行时代理实现的,这个对象永远是一个 proxied(被代理) 对象。 AOP proxy(AOP代理): AOP 框架创建的对象,用来实现 aspect contract(切面契约)(包括通知方法执行等功 能)。 在 Spring 中,AOP 代理可以是 JDK 动态代理或者 CGLIB 代理。 Weaving(织入): 把 aspect(切面)连接到其它的应用程序类型或者对象上,并创建一个被 advised (被通知)的对 象。 这些可以在编译时(例如使用 AspectJ 编译器),类加载时和运行时完成。 Spring 和其他纯 Java AOP 框架一 9.1 Introduction 介绍 9.1.1 AOP concepts 概念 Spring Framework 4.x Reference Documentation 中文翻译 859.1. Introduction 样,在运行时完成织入。 通知的类型: Before advice(前置通知): 在某 join point(连接点)之前执行的通知,但这个通知不能阻止连接点前的执行(除非 它抛出一个异常)。 After returning advice(返回后通知): 在某 join point(连接点)正常完成后执行的通知:例如,一个方法没有抛出任 何异常,正常返回。 After throwing advice(抛出异常后通知): 在方法抛出异常退出时执行的通知。 After (finally) advice(最后通知): 当某join point(连接点)退出的时候执行的通知(不论是正常返回还是异常退 出)。 环绕通知(Around Advice): 包围一个join point(连接点)的通知,如方法调用。这是最强大的一种通知类型。 环绕 通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常 来结束执行。 环绕通知是最常用的一种通知类型。跟 AspectJ 一样,Spring 提供所有类型的通知,我们推荐你使用尽量简单的通知类型来 实现需要的功能。 例如,如果你只是需要用一个方法的返回值来更新缓存,虽然使用环绕通知也能完成同样的事情, 但是你 最好使用 After returning 通知而不是环绕通知。 用最合适的通知类型可以使得编程模型变得简单,并且能够避免很多潜在的 错误。 比如,你不需要调用 JoinPoint (用于Around Advice)的 proceed() 方法,就不会有调用的问题。 在Spring 2.0中,所有的通知参数都是静态类型,因此你可以使用合适的类型(例如一个方法执行后的返回值类型)作为通知 的参数而不是使用一个对象数组。 pointcut(切入点)和 join point(连接点)匹配的概念是 AOP 的关键,这使得 AOP 不同于其它仅仅提供拦截功能的旧技 术。 切入点使得 advice (通知)可独立于 OO 层次。 例如,一个提供声明式事务管理的around 通知可以被应用到一组横跨 多个对象中的方法上(例如服务层的所有业务操作)。 Spring AOP 用纯 Java 实现。它不需要专门的编译过程。Spring AOP 不需要控制类装载器层次,因此它适用于 Servlet 容器 或应用服务器。 Spring 目前仅支持使用方法调用作为join point(连接点)(在 Spring bean 上通知方法的执行)。 虽然可以在不影响到 Spring AOP核心 API 的情况下加入对成员变量拦截器支持,但 Spring 并没有实现成员变量拦截器。 如果你需要通知对成员 变量的访问和更新连接点,可以考虑其它语言,例如 AspectJ。 Spring 实现 AOP 的方法跟其他的框架不同。Spring 并不是要尝试提供最完整的 AOP 实现(尽管 Spring AOP 有这个能 力), 相反的,它其实侧重于提供一种 AOP 实现和 Spring IoC 容器的整合,用于帮助解决在企业级开发中的常见问题。 因此,Spring AOP 通常都和 Spring IoC 容器一起使用。 Aspect 使用普通的bean 定义语法(尽管 Spring 提供了强大 的“autoproxying(自动代理)”功能): 与其他 AOP 实现相比这是一个显著的区别。有些事使用 Spring AOP 是无法轻松或 者高效的完成的,比如说通知一个细粒度的对象。 这种时候,使用 AspectJ 是最好的选择。不过经验告诉我们: 于大多数 在企业级 Java 应用中遇到的问题,只要适合 AOP 来解决的,Spring AOP 都没有问题,Spring AOP 提供了一个非常好的解 决方案。 Spring AOP 从来没有打算通过提供一种全面的 AOP 解决方案来取代AspectJ。 我们相信无论是 proxy-based(基于代理 ) 的框架比如说Spring AOP 亦或是 full-blown 的框架比如说是 AspectJ 都是很有价值的,他们之间的关系应该是互补而不是竞 争的关系。 Spring 可以无缝的整合 Spring AOP,IoC 和 AspectJ,使得所有的 AOP 应用完全融入基于 Spring 的应用体 系。 这样的集成不会影响 Spring AOP API 或者AOP Alliance API;Spring AOP保留了向下兼容性。下一章 10. Spring AOP APIs会详细讨论 Spring AOP API。 一个 Spring Framework 的核心原则是 non-invasiveness(非侵袭性);这意味着你不应该在您的业务/域模型被迫引入框架特 定的类和接口。然而,在一些地方,Spring Framework 可以让你选择引入 Spring Framework 特定的依赖关系到你的代码, 给你这样选择的理由是因为在某些情况下它可能是更容易读或编写一些特定功能。Spring Framework (几乎)总是给你的选 择:你可以自由的做出明智的决定,选择最适合您的特定用例或场景。 9.1.2 Spring AOP capabilities and goals 功能和目标 Spring Framework 4.x Reference Documentation 中文翻译 869.1. Introduction 这样的选择与本章有关的是 AOP 框架(和 AOP 类型)选择。你可以选择AspectJ 和/或 Spring AOP ,你也可以选择 @AspectJ 注解式的方法或Spring 的 XML 配置方式。事实上,本章以介绍 @AspectJ 风格为先不应该被视为 Spring 团队倾 向于 @AspectJ 的方法胜过在 Spring 的XML 配置方式。 见9.4. Choosing which AOP declaration style to use里面有更完整的每种风格的使用原因探讨。 Spring缺省使用标准 JDK dynamic proxies(动态代理)来作为AOP的代理。这样任何接口(或者接口的 set)都可以被代 理。 Spring 也支持使用 CGLIB 代理. 对于需要代理类而不是代理接口的时候CGLIB 代理是很有必要的。 如果一个业务对象并没 有实现一个接口,默认就会使用 CGLIB。 此外,面向接口编程 也是一个最佳实践,业务对象通常都会实现一个或多个接 口。此外,还可以强制的使用 CGLIB,在那些(希望是罕见的)在你需要通知一个未在接口中声明的方法的情况下,或者当 你需要传递一个代理对象作为一种具体类型到方法的情况下。 一个重要的事实是,Spring AOP 是 proxy-based (基于代理)。见第9.6.1,“理解 AOP 代理”理解这个含义 9.1.3 AOP Proxies 代理 Spring Framework 4.x Reference Documentation 中文翻译 879.1. Introduction @AspectJ 可以将切面声明为普通的 Java 类。 AspectJ 5发布的 AspectJ project 中引入了这种 @AspectJ 风格。Spring 使 用了和 AspectJ 5 一样的注解,使用了 AspectJ 提供的一个库来做 pointcut(切点)解析和匹配。 但是,AOP 在运行时仍旧 是纯的 Spring AOP,并不依赖于 AspectJ 的编译器或者 weaver(织入器)。 使用 AspectJ 的编译器或者 weaver(织入器)的话就可以使用完整的AspectJ 语言,我们将在9.8. Using AspectJ with Spring applications中讨论这个问题 为了在 Spring 配置中使用 @AspectJ aspects,你必须首先启用Spring 对基于 @AspectJ aspects 的配置支持, autoproxying(自动代理)基于通知是否来自这些切面。 自动代理是指 Spring 会判断一个bean 是否使用了一个或多个切面 通知,并据此自动生成相应的代理以拦截其方法调用,并且确认通知是否如期进行。 通过 XML 或者 Java 配置来 启用 @AspectJ 支持。在任何情况下,你还需要确保 AspectJ aspectjweaver.jar 在你的应用程 序的类路径中(版本 1.6.8 或以后)。这个库在 AspectJ 发布的 lib 目录中或通过Maven 的 中央存库得到。 使用 @Configuration 和 @EnableAspectJAutoProxy 注解: @Configuration @EnableAspectJAutoProxy public class AppConfig { } 使用 aop:aspectj-autoproxy 元素: 在启用 @AspectJ 支持的情况下,在application context中定义的任意带有一个 @Aspect 切面(拥有 @Aspect 注解)的 bean 都将被Spring自动识别并用于配置在 Spring AOP。 以下例子展示了为了完成一个不是非常有用的切面所需要的最小定 义: 下面是在application context 中的一个常见的 bean 定义,这个 bean 指向一个使用了 @Aspect 注解的 bean 类: 下面是 NotVeryUsefulAspect 类定义,使用了 org.aspectj.lang.annotation.Aspect 注解。 package org.xyz; import org.aspectj.lang.annotation.Aspect; 9.2 关于 @AspectJ 的支持 9.2.1 启用 @AspectJ 支持 用 Java 配置 使用 XML 配置 9.2.2 声明一个切面 Spring Framework 4.x Reference Documentation 中文翻译 889.2. @AspectJ support @Aspect public class NotVeryUsefulAspect { } 切面(用 @Aspect 注解的类)和其他类一样有方法和字段定义。他们也可能包括切入点,通知和引入(inter-type)声明。 你可以注册 切面 像其他 bean 一样在 Spring 的 XML 进行配置,或自动通过类路径扫描-就像任何其他的 Spring 管理的 bean。然而,请注意,@Aspect 的注解是不足以在 classpath 自动检测到了:为了这个目的,你需要添加一个单独的 @Component 的注解(或者自定义stereotype annotation 即 qualifies,作为 Spring 组件的扫描规则)。 在 Spring AOP 中,它是不可能使自己的切面成为 其他切面的通知的目标的。类上的 @Aspect 注解标记 它成为一个切面, 因此从 auto-proxying 中排除了它。 回想一下,切入点决定了连接点关注的内容,使得我们可以控制通知什么执行。 Spring AOP 只支持 Spring bean 方法执行 连接点。所以你可以把切入点看做是匹配 Spring bean 上的方法执行。 一个切入点声明有两个部分:一个包含名字和任意参 数的签名,还有一个切入点表达式,该表达式决定了我们关注那个方法的执行。 在 @AspectJ 中,一个切入点实际就是一个 普通的方法定义提供的一个签名,并且切入点表达式使用 @Pointcut 注解来表示(这个方法的返回类型必须是 void)。 如下的例子定义了一个切入点'anyOldTransfer',这个切入点匹配了任意名为 transfer 的方法执行 @Pointcut("execution(* transfer(..))")// the pointcut expression private void anyOldTransfer() {}// the pointcut signature 切入点表达式,也就是 @Pointcut 注解的值,是正规的 AspectJ 5 切入点表达式。 如果你想要更多了解 AspectJ 的 切入点 语言,请参见AspectJ 编程指南(如果要了解扩展请参阅 AspectJ 5 开发手册) 或者其他人写的关于 AspectJ 的书,例如 Colyer et. al.著的《Eclipse AspectJ》或者 Ramnivas Laddad著的《AspectJ in Action》。 Spring AOP 支持在切入点表达式中使用如下的 AspectJ pointcut designators (切入点指定者 PCD) : 其他的切入点类型 完整的 AspectJ 切入点语言支持额外的切入点指定者,但是 Spring 不支持这个功能。 他们分别是call, get, set, preinitialization, staticinitialization, initialization, handler, adviceexecution, withincode, cflow, cflowbelow, if, @this, 和 @withincode 。 在 Spring AOP 中使用这些指定者将会导致抛出IllegalArgumentException 异常。 在 Spring AOP 设置切入点指定者可能会在未来的发布中进行扩展,用来支持更多 AspectJ 切入点指定者。 execution - 匹配方法执行的连接点,这是你将会用到的 Spring 的最主要的切入点指定者。 within - 限定匹配特定类型的连接点(在使用 Spring AOP 的时候,在匹配的类型中定义的方法的执行)。 this - 限定匹配特定的连接点(使用 Spring AOP 的时候方法的执行),其中 bean reference(Spring AOP 代理)是指 定类型的实例。 target - 限定匹配特定的连接点(使用 Spring AOP 的时候方法的执行),其中目标对象(被代理的 appolication object )是指定类型的实例。 args - 限定匹配特定的连接点(使用 Spring AOP 的时候方法的执行),其中参数是指定类型的实例。 @target - 限定匹配特定的连接点(使用 Spring AOP 的时候方法的执行),其中执行的对象的类已经有指定类型的注 解。 @args - 限定匹配特定的连接点(使用 Spring AOP 的时候方法的执行),其中实际传入参数的运行时类型有指定类型 的注解。 9.2.3 声明一个切入点 支持的切入点指定者 Spring Framework 4.x Reference Documentation 中文翻译 899.2. @AspectJ support @within - 限定匹配特定的连接点,其中连接点所在类型已指定注解(在使用 Spring AOP 的时候,所执行的方法所在类 型已指定注解)。 @annotation - 限定匹配特定的连接点(使用 Spring AOP 的时候方法的执行),其中连接点的主题有某种给定的注解。 因为 Spring AOP 限制了连接点必须是方法执行级别的,pointcut designators 的讨论也给出了一个定义,这个定义和 AspectJ 的编程指南中的定义相比显得更加狭窄。 除此之外,AspectJ 它本身有基于类型的语义,在执行的连接 点'this'和'target'都是指同一个对象,也就是执行方法的对象。 Spring AOP 是一个基于代理的系统,并且严格区分代理对象 本身(对应于'this')和背后的目标对象(对应于'target') 由于 Spring 的 AOP 框架基于代理的本质,protected 方法通过定义不拦截来实现的,无论是对 JDK 代理(这并不适用)还是 CGLIB 代理(这在技术上是可行的,但不值得推荐的用于AOP)。因此,任何给定的切入点将只匹配 public 方法! 如果您的拦截需求包括 protected/private 方法或者构造函数,考虑使用 Spring-driven 原生的 AspectJ 织入而不是 Spring 的基 于代理的 AOP 框架。这就构成了一个 AOP 使用具有不同特点的不同模式,所以一定要在做决定之前首先要让自己熟悉织入。 Spring AOP 还支持另一个 PCD 命名的 bean 。PCD 允许您限制连接点匹配的特定命名的 Spring bean,或者一组名为 Spring bean(当使用通配符)。 bean PCD 有以下形式: bean(idOrNameOfBean) idOrNameOfBean 令牌是可以任何 Spring bean 的名称:使用 * 通配符支持字符提供限制,所以如果你为 Spring bean 建立一 些命名约定可以很容易地编写一个 bean PCD表达出来。一样与其他切入点指示器、 bean PCD 可以是 &&'ed, ||'ed, 和 ! (否 定) 注意: bean PCD 只在 Spring AOP 支持-而不在原生的 AspectJ 织入。这个是 Spring 特有对 AspectJ 定义的 PCD 的扩展 切入点表达式可以使用 &&, || 和 ! 来合并.还可以通过名字来指向切入点表达式。 以下的例子展示了三种切入点表达 式: anyPublicOperation (在一个方法执行连接点代表了任意 public 方法的执行时匹配); inTrading (在一个代表了在交 易模块中的任意的方法执行时匹配) 和 tradingOperation (在一个代表了在交易模块中的任意的公共方法执行时匹配)。 @Pointcut("execution(public * *(..))") private void anyPublicOperation() {} @Pointcut("within(com.xyz.someapp.trading..*)") private void inTrading() {} @Pointcut("anyPublicOperation() && inTrading()") private void tradingOperation() {} 就上所示的,从更小的命名组件来构建更加复杂的切入点表达式是一种最佳实践。 当用名字来指定切入点时使用的是常见的 Java成员可视性访问规则。 (比如说,你可以在同一类型中访问私有的切入点,在继承关系中访问受保护的切入点,可以在 任意地方访问公共切入点。 成员可视性访问规则不影响到切入点的 匹配。 当开发企业级应用的时候,你通常会想要从几个切面来参考模块化的应用和特定操作的集合。 我们推荐定义一 个“SystemArchitecture”切面来捕捉常见的切入点表达式。一个典型的切面可能看起来像下面这样: package com.xyz.someapp; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; 合并切入点表达式 共享常见的切入点定义 Spring Framework 4.x Reference Documentation 中文翻译 909.2. @AspectJ support @Aspect public class SystemArchitecture { /** * A join point is in the web layer if the method is defined * in a type in the com.xyz.someapp.web package or any sub-package * under that. */ @Pointcut("within(com.xyz.someapp.web..*)") public void inWebLayer() {} /** * A join point is in the service layer if the method is defined * in a type in the com.xyz.someapp.service package or any sub-package * under that. */ @Pointcut("within(com.xyz.someapp.service..*)") public void inServiceLayer() {} /** * A join point is in the data access layer if the method is defined * in a type in the com.xyz.someapp.dao package or any sub-package * under that. */ @Pointcut("within(com.xyz.someapp.dao..*)") public void inDataAccessLayer() {} /** * A business service is the execution of any method defined on a service * interface. This definition assumes that interfaces are placed in the * "service" package, and that implementation types are in sub-packages. * * If you group service interfaces by functional area (for example, * in packages com.xyz.someapp.abc.service and com.xyz.someapp.def.service) then * the pointcut expression "execution(* com.xyz.someapp..service.*.*(..))" * could be used instead. * * Alternatively, you can write the expression using the 'bean' * PCD, like so "bean(*Service)". (This assumes that you have * named your Spring service beans in a consistent fashion.) */ @Pointcut("execution(* com.xyz.someapp..service.*.*(..))") public void businessService() {} /** * A data access operation is the execution of any method defined on a * dao interface. This definition assumes that interfaces are placed in the * "dao" package, and that implementation types are in sub-packages. */ @Pointcut("execution(* com.xyz.someapp.dao.*.*(..))") public void dataAccessOperation() {} } 定义的切入点可以指任何一个切面,你需要一个切入点表达式。例如,服务层的事务,你可以写: 在 9.3. Schema-based AOP support中讨论 标签。 在 12. Transaction Management 中讨论 事务标签。 Spring Framework 4.x Reference Documentation 中文翻译 919.2. @AspectJ support Spring AOP 用户可能会经常使用 execution pointcut designator。执行表达式的格式如下: execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?) 除了返回类型模式,名字模式和参数模式以外,所有的部分都是可选的。 返回类型模式决定了方法的返回类型必须依次匹配 一个连接点。 你会使用的最频繁的返回类型模式是 * ,它代表了匹配任意的返回类型。 一个全称限定的类型名将只会匹配 返回给定类型的方法。名字模式匹配的是方法名。 你可以使用 * 通配符作为所有或者部分命名模式。 参数模式稍微有点复 杂: () 匹配了一个不接受任何参数的方法, 而 (..) 匹配了一个接受任意数量参数的方法(零或者更多)。 模式 (*) 匹 配了一个接受一个任何类型的参数的方法。 模式 (*,String) 匹配了一个接受两个参数的方法,第一个可以是任意类型,第 二个则必须是 String 类型。 请参见 AspectJ编程指南的 Language Semantics 部分。 下面给出一些常见切入点表达式的例子。 任意 public 方法的执行: execution(public * *(..)) 任何一个以“set”开始的方法的执行: execution(* set*(..)) AccountService 接口的任意方法的执行: execution(* com.xyz.service.AccountService.*(..)) 定义在service包里的任意方法的执行: execution(* com.xyz.service.*.*(..)) 定义在service包或者子包里的任意方法的执行: execution(* com.xyz.service..*.*(..)) 在service包里的任意连接点(在Spring AOP中只是方法执行) : within(com.xyz.service.*) 在service包或者子包里的任意连接点(在Spring AOP中只是方法执行) : within(com.xyz.service..*) 实现了 AccountService 接口的代理对象的任意连接点(在Spring AOP中只是方法执行) : 例子 Spring Framework 4.x Reference Documentation 中文翻译 929.2. @AspectJ support this(com.xyz.service.AccountService) 'this'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得代理对象可以在通知体内访问到的部分。 实现了 AccountService 接口的目标对象的任意连接点(在Spring AOP中只是方法执行) : target(com.xyz.service.AccountService) 'target'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得目标对象可以在通知体内访问到的部分。 任何一个只接受一个参数,且在运行时传入的参数实现了 Serializable 接口的连接点 (在Spring AOP中只是方法执行) args(java.io.Serializable) 'args'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得方法参数可以在通知体内访问到的部分。 请注意在例子中给出的切入点不同于 execution(* *(java.io.Serializable)) 只有在动态运行时候传入参数是可序列化的 (Serializable)才匹配,而 execution 在传入参数的签名声明的类型实现了 Serializable 接口时候匹配。 有一个 @Transactional 注解的目标对象中的任意连接点(在Spring AOP 中只是方法执行) @target(org.springframework.transaction.annotation.Transactional) '@target' 也可以在binding form中使用:请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的 部分。 任何一个目标对象声明的类型有一个 @Transactional 注解的连接点(在Spring AOP中只是方法执行) @within(org.springframework.transaction.annotation.Transactional) '@within'也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到 的部分。 任何一个执行的方法有一个 @Transactional annotation的连接点(在Spring AOP中只是方法执行) @annotation(org.springframework.transaction.annotation.Transactional) '@annotation' 也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访 问到的部分。 任何一个接受一个参数,并且传入的参数在运行时的类型实现了 @Classified annotation的连接点(在Spring AOP中只是方 法执行) @args(com.xyz.security.Classified) '@args'也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得 annotation 对象可以在通知体内访问到 的部分。 Spring Framework 4.x Reference Documentation 中文翻译 939.2. @AspectJ support 任何 Spring bean 命名为 tradeService 的切入点(在Spring AOP中只是方法执行): bean(tradeService) 任何 Spring bean 命名符合正则表达式为 *Service 的切入点(在Spring AOP中只是方法执行): bean(*Service) 在编译过程中,AspectJ 执行切入点来尝试和优化匹配性能。检查代码确认每个连接点是否都匹配(静态或者动态)给出的 切入点,这个代价是昂贵的。(动态匹配意味着匹配不能完全在静态分析上确认,而是用一个在代码运行时的代码测试来了 来确认是否真实匹配了)。当第一次遇到切入点声明,AspectJ 将会重写一个最佳形式用于匹配执行。啥意思?基本切入点 被重写为 DNF (Disjunctive Normal Form) ,切入点组件被分类,这样,评估检查代价更低。意味着无需担心不同切入点 designators(编号)之间的性能,可以任意顺序声明切入点来使用它们。 然而,AspectJ 只能工作于告诉他的事,为了优化匹配性能,你要考虑他们尝试获取和搜索空间来匹配可能的定义。现存的 designators(编号)主要有三类: kinded, scoping 和 context: Kinded:选择一个特殊的 join point(连接点),如: execution, get, set, call, handler Scoping:选择一个感兴趣的(很多类型的) join point(连接点)组如: within, withincode Context:匹配(和可选绑定)基于上下文 ,如: this, target, @annotation 9.2.4 声明 advice Advice 与切入点表单式相关联,并且与切入点匹配时执行 before, after, 或 around 方法。切入点表达式可以是一个命名切入 点的引用,也可以是就地声明切入点表达式。 Before advice 使用 @Before 注解来声明 import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class BeforeExample { @Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation()") public void doAccessCheck() { // ... } } 如果是就地切入点表达式,上面例子可以重写为: import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class BeforeExample { @Before("execution(* com.xyz.myapp.dao.*.*(..))") public void doAccessCheck() { 编写好的切入点 Before advice Spring Framework 4.x Reference Documentation 中文翻译 949.2. @AspectJ support // ... } } 当匹配一个方法执行正常返回时,After returning advice 执行。声明使用 @AfterReturning 注解 import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.AfterReturning; @Aspect public class AfterReturningExample { @AfterReturning("com.xyz.myapp.SystemArchitecture.dataAccessOperation()") public void doAccessCheck() { // ... } } 注意:可以声明多个 advice 有时需要访问 advice 返回的真实值,可以使用 @AfterReturning 绑定到返回值: import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.AfterReturning; @Aspect public class AfterReturningExample { @AfterReturning( pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()", returning="retVal") public void doAccessCheck(Object retVal) { // ... } } returning 属性对应了 advice 方法的参数名称,当方法执行返回,返回值将会传递给对于的 advice 方法的参数 值。 returning 条款还限制匹配只有那些返回一个指定类型值的方法执行(在本例中 Object ,它将匹配任何返回值)。 注意:当使用 after-returning advice,不可能返回一个完全不同的引用。 当匹配到方法执行抛出异常时,After throwing advice 执行。使用 @AfterThrowing 注解: import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.AfterThrowing; @Aspect public class AfterThrowingExample { @AfterThrowing("com.xyz.myapp.SystemArchitecture.dataAccessOperation()") public void doRecoveryActions() { // ... } } After returning advice After throwing advice Spring Framework 4.x Reference Documentation 中文翻译 959.2. @AspectJ support Often you want the advice to run only when exceptions of a given type are thrown, and you also often need access to the thrown exception in the advice body. Use the throwing attribute to both restrict matching (if desired, use Throwable as the exception type otherwise) and bind the thrown exception to an advice parameter. Spring Framework 4.x Reference Documentation 中文翻译 969.2. @AspectJ support Spring Framework 4.x Reference Documentation 中文翻译 979.3. Schema-based AOP support Spring Framework 4.x Reference Documentation 中文翻译 989.4. Choosing which AOP declaration style to use Spring Framework 4.x Reference Documentation 中文翻译 999.5. Mixing aspect types Spring Framework 4.x Reference Documentation 中文翻译 1009.6. Proxying mechanisms Spring Framework 4.x Reference Documentation 中文翻译 1019.7. Programmatic creation of @AspectJ Proxies Spring Framework 4.x Reference Documentation 中文翻译 1029.8. Using AspectJ with Spring applications Spring Framework 4.x Reference Documentation 中文翻译 1039.9. Further Resources Spring Framework 4.x Reference Documentation 中文翻译 10410. Spring AOP APIs Spring Framework 4.x Reference Documentation 中文翻译 10510.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 10610.2. Pointcut API in Spring Spring Framework 4.x Reference Documentation 中文翻译 10710.3. Advice API in Spring Spring Framework 4.x Reference Documentation 中文翻译 10810.4. Advisor API in Spring Spring Framework 4.x Reference Documentation 中文翻译 10910.5. Using the ProxyFactoryBean to create AOP proxies Spring Framework 4.x Reference Documentation 中文翻译 11010.6. Concise proxy definitions Spring Framework 4.x Reference Documentation 中文翻译 11110.7. Creating AOP proxies programmatically with the ProxyFactory Spring Framework 4.x Reference Documentation 中文翻译 11210.8. Manipulating advised objects Spring Framework 4.x Reference Documentation 中文翻译 11310.9. Using the "auto-proxy" facility Spring Framework 4.x Reference Documentation 中文翻译 11410.10. Using TargetSources Spring Framework 4.x Reference Documentation 中文翻译 11510.11. Defining new Advice types Spring Framework 4.x Reference Documentation 中文翻译 11610.12. Further resources Spring Framework 4.x Reference Documentation 中文翻译 11711. Testing Spring Framework 4.x Reference Documentation 中文翻译 11811.1. Introduction to Spring Testing Spring Framework 4.x Reference Documentation 中文翻译 11911.2. Unit Testing Spring Framework 4.x Reference Documentation 中文翻译 12011.3. Integration Testing Spring Framework 4.x Reference Documentation 中文翻译 12111.4. Further Resources Spring Framework 4.x Reference Documentation 中文翻译 122IV. 数据访问 Spring Framework 4.x Reference Documentation 中文翻译 12312. Transaction Management Spring Framework 4.x Reference Documentation 中文翻译 12412.1. Introduction to Spring Framework transaction management Spring Framework 4.x Reference Documentation 中文翻译 12512.2. Advantages of the Spring Framework’s transaction support model Spring Framework 4.x Reference Documentation 中文翻译 12612.3. Understanding the Spring Framework transaction abstraction Spring Framework 4.x Reference Documentation 中文翻译 12712.4. Synchronizing resources with transactions Spring Framework 4.x Reference Documentation 中文翻译 12812.5. Declarative transaction management Spring Framework 4.x Reference Documentation 中文翻译 12912.6. Programmatic transaction management Spring Framework 4.x Reference Documentation 中文翻译 13012.7. Choosing between programmatic and declarative transaction management Spring Framework 4.x Reference Documentation 中文翻译 13112.8. Application server-specific integration Spring Framework 4.x Reference Documentation 中文翻译 13212.9. Solutions to common problems Spring Framework 4.x Reference Documentation 中文翻译 13312.10. Further Resources Spring Framework 4.x Reference Documentation 中文翻译 13413. DAO support Spring Framework 4.x Reference Documentation 中文翻译 13513.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 13613.2. Consistent exception hierarchy Spring Framework 4.x Reference Documentation 中文翻译 13713.3. Annotations used for configuring DAO or Repository classes Spring Framework 4.x Reference Documentation 中文翻译 13814. Data access with JDBC Spring Framework 4.x Reference Documentation 中文翻译 13914.1. Introduction to Spring Framework JDBC Spring Framework 4.x Reference Documentation 中文翻译 14014.2. Using the JDBC core classes to control basic JDBC processing and error handling Spring Framework 4.x Reference Documentation 中文翻译 14114.3. Controlling database connections Spring Framework 4.x Reference Documentation 中文翻译 14214.4. JDBC batch operations Spring Framework 4.x Reference Documentation 中文翻译 14314.5. Simplifying JDBC operations with the SimpleJdbc classes Spring Framework 4.x Reference Documentation 中文翻译 14414.6. Modeling JDBC operations as Java objects Spring Framework 4.x Reference Documentation 中文翻译 14514.7. Common problems with parameter and data value handling Spring Framework 4.x Reference Documentation 中文翻译 14614.8. Embedded database support Spring Framework 4.x Reference Documentation 中文翻译 14714.9. Initializing a DataSource Spring Framework 4.x Reference Documentation 中文翻译 14815. 对象关系映射(ORM)数据访问 Spring Framework 支持集成 Hibernate, Java Persistence API (JPA) 和 Java Data Objects (JDO) 用于资源管理、数据访问 对象(DAO)的实现,和事务策略。例如,对于 Hibernate 有一流的支持,使用方便的 IoC 特性,解决许多典型的 Hibernate 集成问 题。您可以通过依赖注入配置的所有 O/R (对象关系) 映射工具的特性。他们可以参与 Spring 的资源和事务管理,他们符合 Spring 的通用事务和 DAO 异常层次结构。建议集成风格是在 Hibernate, JPA, 和 JDO APIs 中使用 DAO 。旧的 Spring DAO 模板不再推荐使用;然而,关于风格的论述可以见32.1节,“经典的 ORM 使用”。 当你创建数据访问应用时,Spring 能对你选择的 ORM 层进行显着的增强。你根据你的需求进行尽可能多的集成支持,同时 需要比这种整合在建一个类似的基础设施时的内部风险。通过库,你可以使用很多的 ORM 的支持,不用管技术,因为一切 都是设计成一组可重用的 JavaBean。ORM 在 Spring IoC 容器便于配置和部署。因此,本文中的大多数示例配置显示在 Spring 容器里。 使用 Spring Framework 来创建您的 ORM DAO 好处包括: 更容易测试。Spring 的 IoC 方法便于交换实现和配置 Hibernate SessionFactory 实例,JDBC DataSource (数据源)实例, 事务管理,以及映射对象实现(如果需要)。这反过来使其更容易隔离测试每一块持续相关代码。 常见的数据访问异常。Spring 可以从你的 ORM 工具包装异常,将他们从专有的(可能检查)异常转为共同运行时 DataAccessException 层次。这个特性允许您处理大多数持久化的异常不可恢复的,而且只出现在适当的层,没有恼人的 捕捉、抛出、和异常声明。当然根据需要你仍然可以捕获和处理异常。记住,JDBC 异常(包括数据库特殊的方言)也转换 为相同的层次结构,这意味着您可以在使用 JDBC 执行一些操作时拥有一致的编程模型。 通用资源管理。Spring 应用程序上下文可以处理的定位和配置Hibernate SessionFactory 实例,JPA EntityManagerFactory 实例,JDBC DataSource (数据源)实例,和其他相关资源。这使得这些值易于管理和改变。Spring 提 供了高效、简单和安全处理持久性的资源。例如,关联代码来使用 Hibernate ,通常需要使用相同的 Hibernate Session , 以确保高效和适当的事务处理。Spring 很容易创建和透明地将 Session 绑定到当前线程,通过使用 Hibernate SessionFactory 来暴露出当前 Session 。因此,针对任何本地或 JTA 事务环境,Spring 解决许多在典型的 Hibernate 使 用中的惯性问题。 集成事务管理。可以通过声明式的,面向方面的编程(AOP)风格方法拦截器包装你的 ORM 代码通过吗,可以采 用 @Transactional 注释或通过显式配置事务 AOP advice 在一个 XML 配置文件中。在这两种情况下,都是可以为您处理 事务语义和异常处理(回滚,等等)。如下面所讨论的资源和事务管理,你也可以交换不同的事务管理器,而不影响 ORM 相关 的代码。例如,您可以在相同的全面服务(如声明性事务)的两个场景,实现本地事务和 JTA 之间交换。另外,JDBC 相关的 代码可以完全集成事务到你使用的 ORM 代码中。这是对于数据访问有用,但不适合 ORM 中的批处理和 BLOB 流等,这仍 然需要在ORM操作 交换共同的事务。 为更全面了解的 ORM 的支持,包括支持替代数据库技术,如 MongoDB 数据库,您可能希望查看 Spring Data 配套的项目。如果 你是一个 JPA 用户,Getting Started Accessing Data with JPA提供了一个很好的介绍。 15.1 Introduction to ORM with Spring 介绍 Spring 中的 ORM Spring Framework 4.x Reference Documentation 中文翻译 14915.1. Spring 中的 ORM 本节强调的 注意事项应用与所有的 ORM 技术。15.3. Hibernate这节提供了更多细节,同时展示了这些特性和具体上下文的 配置。 Spring 的 ORM 集成的主要目标是明确的应用程序分层,包括在任何数据访问、事务技术和松耦合的应用程序对象。没有更多 的业务服务依赖于数据访问或事务策略,不再资源查找硬编码,不再强制替换单例,没有更多的自定义服务注册。一个简单的和 一致的方法来连接应用程序对象,让他们尽可能的对容器依赖是可以重用并且是自由。所有个人数据访问特性可用的,但可以与 Spring 应用程序上下文的概念集成,提供基于 xml 的配置和交叉引用的普通 JavaBean 实例而不需要 Spring-aware(Spring 的意识)。在一个典型的 Spring 应用程序中,许多重要的对象是 JavaBean:数据访问模板,数据访问对象,事务管理器,使用数据 访问对象和事务管理器的业务服务, web 视图解析器,使用业务服务的 web 控制器,等等。 典型的商业应用是用重复的资源管理代码杂乱的堆积起来的。很多项目试图创造自己的解决方案,有时为了编程方便来牺牲 故障的处理。Spring 提倡简单的处理适当资源的方案,即在JDBC的案例 IoC 通过模板和在 ORM 技术应用 AOP 拦截器。 基础设施提供适当的资源处理,并且能将特定的 API 异常适当的转换为一个未检查的基础的异常层次结构。Spring 引入了 DAO 异常层次结构,适用于任何的数据访问策略。对于直接的 JDBC,在前一节提到的 JdbcTemplate 类提供了连接处理和将 SQLException 适当的转换为 DataAccessException 层次结构,其中包括将 具体数据库 SQL 错误代码转为有意义的异常类。 对于 ORM 技术,见下一节,如何得到相同异常转换的好处。 当涉及到事务管理, JdbcTemplate 类与 Spring 的事务支持挂钩,并且通过各自的 Spring 事务管理器支持 JTA 和 JDBC 事 务。为支持 ORM 技术 Spring 提供了通过与 JTA 支持类似的 Hibernate,JPA,和 JDO 事务管理器来实现对 Hibernate, JPA 和 JDO 支持。更多事务的支持,详细信息,参见第12章,事务管理。 当你在 DAO 中使用 Hibernate、JPA 或 JDO 时,你必须决定如何处理持久化技术的原生异常类。运用不同的技术,DAO 会抛 出 HibernateException 、 PersistenceException 或 JDOException 的子类。这些异常都是运行时的异常,不需要声明或捕获。你 可能必须处理 IllegalArgumentException 和 IllegalStateException 。这意味着调用者只能将异常处理成为一个通常为致命的 问题,除非他们想要依赖于持久化技术自身的异常结构。捕捉乐观锁定失败等具体原因是不可能的除非把调用者与实现策略相 联系。取消这交换是可接受的对于应用程序是基于 ORM 和/或 不需要任何特殊的异常处理。然而,Spring 通过 @Repository 注解 来使异常透明的转化: @Repository public class ProductDaoImpl implements ProductDao { // class body here... } 15.2 General ORM integration considerations常见的 ORM 集成方面的注意事项 15.2.1 Resource and transaction management 资源和事务管理 15.2.2 Exception translation 异常转化 Spring Framework 4.x Reference Documentation 中文翻译 15015.2. 常见的 ORM 集成方面的注意事项 postprocessor 会自动寻找所有异常转换器( 实现 PersistenceExceptionTranslator 接口),建议所有 bean 标有 @Repository 注 解,以便发现的转换器可以在抛出异常时拦截和应用适当的转换。 总之:您可以实现 DAO 基于纯持久化技术的API和注解,同时仍然受益于Spring 管理事务,依赖注入、和透明将异常转换(如果 需要)为 Spring 的自定义的异常层次结构。 Spring Framework 4.x Reference Documentation 中文翻译 15115.2. 常见的 ORM 集成方面的注意事项 现在要开始谈下 Spring 环境中的 Hibernate 3,用它来展示 Spring 对集成 O/R 映射的方法。本节将详细讨论许多问题,并显 示不同的 DAO 实现和事务界定。大多数这些模式可以直接从所有其他支持 ORM 的工具中转换。以下部分在本章将覆盖其 他的 ORM 技术,并显示简短的例子。 对于Spring 4.0, Spring 需要 Hibernate 3.6 或者更高版本 为了避免应用程序对象与硬编码的资源查找想绑定,您可以定义资源如 JDBC DataSource 或者 Hibernate SessionFactory 为 Spring 容器的 bean。应用对象需要通过对 bean 的引用来访问资源接受引用,就如在下一节中说明的 DAO 的定义。 以下摘录自 XML 应用程序上下文定义,展示了如何设置 JDBC DataSource 或者 Hibernate SessionFactory : product.hbm.xml hibernate.dialect=org.hibernate.dialect.HSQLDialect 从 Jakarta Commons DBCP BasicDataSource 转为 JNDI-located DataSource , 主要的配置为: 您还可以访问 JNDI-located SessionFactory ,使用 Spring 的 JndiObjectFactoryBean / 来检索和暴露他。然 而,通常在 EJB 环境外不常用。 基于平常的 Hibernate 3 API 来实现 DAO Hibernate 3 有一个特性称为上下文会话,Hibernate 本身在每个事务管理一个当前 Session 。这是大致相当于 Spring 的 每个 事务一个当前 Hibernate Session 的同步。相应的 DAO 实现像下面的例子,基于普通Hibernate API: 15.3 Hibernate 15.3.1 SessionFactory setup in a Spring container 在 Spring 容器中设置 SessionFactory 15.3.2 Implementing DAOs based on plain Hibernate 3 API Spring Framework 4.x Reference Documentation 中文翻译 15215.3. Hibernate public class ProductDaoImpl implements ProductDao { private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public Collection loadProductsByCategory(String category) { return this.sessionFactory.getCurrentSession() .createQuery("from test.Product product where product.category=?") .setParameter(0, category) .list(); } } 这种风格类似于 Hibernate 参考文档和例子,除了在一个实例变量中保存 SessionFactory 。我们强烈建议基于实例的设置,替 换老派的Hibernate 的 CaveatEmptor 示例应用程序中的 static HibernateUtil 类。(一般来说,不保留任何资源 static 变量, 除非绝对必要) 上面的 DAO 是依赖注入模式:这正好符合 Spring IoC 容器,就像对Spring 的 HibernateTemplate 编码。当然,这种 DAO 也可 以在普通的 Java 设置(例如,在单元测试)。简单的实例化,并用所需的工厂引用调用 setSessionFactory(..) 。Spring bean 定 义 DAO 就像下面一样: DAO 风格的主要优点是,它只依赖于 Hibernate API ,而没有引进任何Spring 必需的类。从非侵入性的视角看这当然是有吸 引力的,对Hibernate 开发者来说无疑会感觉更自然。 然而,DAO 将平常的 HibernateException (这是未检查的,所以不需要声明或者捕获),这意味着调用者当异常为一个普通 的致命问题——除非他们想要依赖于 Hibernate 自身的异常结构。捕捉乐观锁定失败等具体原因是不可能除非把调用者与实 现策略相联系。取消这交换是可接受的对于应用程序是基于 Hibernate 和/或 不需要任何特殊的异常处理。 幸运的是,Spring 的 LocalSessionFactoryBean 支持 Hibernate SessionFactory.getCurrentSession() 方法用于任何 Spring 事务 策略,返回当前 Spring 管理的事务 Session 即使是 HibernateTransactionManager. 。当然,这种方法的标准行为返回仍然是当 前 Session 与持续的JTA事务有关。这种行为适用于不管您使用是Spring 的 JtaTransactionManager ,EJB容器管理的事务 (CMT),或 JTA。 总之:你可以基于平常的 Hibernate 3 API 来实现 DAO,同时仍然能够参与 Spring 管理事务。 建议你使用 Spring 声明式事务的支持,这使您能够代替显式事务划分 API调用 AOP 事务拦截器中的 Java 代码。这个事务拦 截器可以配置 Spring容器通过使用 Java 注释或 XML。这个声明式事务能力允许您保持业务服务中的重复性事务划分代码码 更自由,并且让你只关注添加业务逻辑,而这是您的应用程序的真正价值。 在继续之前,强烈建议你读12.5节,“事务管理”如果你还没有这样做。 此外,事务语义比如传播行为和隔离水平可以在配置文件的改变,不影响业务服务的实现。 下面的示例说明如何使用 XML 配置 AOP 事务拦截器,一个简单的服务类: 15.3.3 Declarative transaction demarcation 声明式事务划分 Spring Framework 4.x Reference Documentation 中文翻译 15315.3. Hibernate 下面是要处理的服务类 public class ProductServiceImpl implements ProductService { private ProductDao productDao; public void setProductDao(ProductDao productDao) { this.productDao = productDao; } // notice the absence of transaction demarcation code in this method // Spring's declarative transaction infrastructure will be demarcating // transactions on your behalf public void increasePriceOfAllProductsInCategory(final String category) { List productsToChange = this.productDao.loadProductsByCategory(category); // ... } } 我们还展示了一个基于配置属性的支持,在下面的例子中。你通过 @Transactional 注释的服务层,并引导 Spring 容器找到这 些注释,这些注释的方法提供事务性语义。 public class ProductServiceImpl implements ProductService { private ProductDao productDao; public void setProductDao(ProductDao productDao) { this.productDao = productDao; } Spring Framework 4.x Reference Documentation 中文翻译 15415.3. Hibernate @Transactional public void increasePriceOfAllProductsInCategory(final String category) { List productsToChange = this.productDao.loadProductsByCategory(category); // ... } @Transactional(readOnly = true) public List findAllProducts() { return this.productDao.findAllProducts(); } } 正如你可以看到下面的配置实例,配置更加简化,与上述 XML 实例,同时还提供了在服务层的代码注释驱动相同的功能。所 有您需要提供的是TransactionManager 的实现和"" 实体 可以在高级的应用中划分事务,在这样的底层数据访问服务生成任意数量的操作。限制也不存在于周边业务服务的实现;它只 需要一个 Spring PlatformTransactionManager 。再次,后者可以来自任何地方,但最好是通过 setTransactionManager(..) 方法 来对 bean 引用,正如由 setProductDao(..) 方法来设置 productDAO 。下面的代码片段显示了在Spring 应用程序上下文中定义 一个事务管理器和业务服务,以及一个业务方法实现: 15.3.4 Programmatic transaction demarcation 编程式事务划分 Spring Framework 4.x Reference Documentation 中文翻译 15515.3. Hibernate public class ProductServiceImpl implements ProductService { private TransactionTemplate transactionTemplate; private ProductDao productDao; public void setTransactionManager(PlatformTransactionManager transactionManager) { this.transactionTemplate = new TransactionTemplate(transactionManager); } public void setProductDao(ProductDao productDao) { this.productDao = productDao; } public void increasePriceOfAllProductsInCategory(final String category) { this.transactionTemplate.execute(new TransactionCallbackWithoutResult() { public void doInTransactionWithoutResult(TransactionStatus status) { List productsToChange = this.productDao.loadProductsByCategory(category); // do the price increase... } }); } } Spring TransactionInterceptor 允许任何检查的应用异常可以跟着回调代码抛出,而 TransactionTemplate 是限制于未检查 的回调的异常。当遇到一个未检查的应用异常或者是事务被应用(通过 TransactionStatus )标记为 rollback-only(只回滚) , TransactionTemplate 触发回滚事务。默认时 TransactionInterceptor 表现是一样的,但是允许在每个方法中配置回滚策略。 TransactionTemplate 和 TransactionInterceptor 代表了对 PlatformTransactionManager 实例的实际事务处理,在 Hibernate 的应用中它们可以是一个 HibernateTransactionManager (一个Hibernate 的 SessionFactory ,在引擎下使用的 是 ThreadLocal Session )或 JtaTransactionManager (委派到容器的 JTA 子系统)。你甚至可以使用一个自定义 的 PlatformTransactionManager 实现。从原生 Hibernate 事务管理 转到 JTA,如你的某些应用程序部署具有分布式事务处理 的要求,那么这仅仅是一个配置的问题,只要将 Hibernate 事务管理简单的替换为 Spring 的 JTA 即可。两个的事务划分和数 据访问代码的不用改变,因为他们只是使用了通用的事务管理 API。 对于分布式事务跨多个 Hibernate 会话工厂,只要简单地把 JtaTransactionManager 与具有多个定义 的 LocalSessionFactoryBean 组合成为一个事务策略。每个 DAO 得到一个特定的 SessionFactory 的引用传递到其相应的 bean 属性。如果所有底层的 JDBC 数据源的事务容器,业务服务可以划分事务到任意数量的DAO 和任何数量的会话工厂,而这 无需没有特殊的处理,只要是使用 JtaTransactionManager 策略。 product.hbm.xml hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.show_sql=true 15.3.5 Transaction management strategies 事务管理策略 Spring Framework 4.x Reference Documentation 中文翻译 15615.3. Hibernate inventory.hbm.xml hibernate.dialect=org.hibernate.dialect.OracleDialect HibernateTransactionManager 和 JtaTransactionManager 允许适当的 JVM 级别的 Hibernate 缓存处理,而不需要容器特定的事 务管理查找或 JCA 连接器(如果你不使用 EJB 启动事务)。 HibernateTransactionManager 可以为一个特定的 DataSource 导出 Hibernate JDBC Connection 到普通 JDBC 访问代码。此功 能允许高级的混合 Hibernate 和 JDBC 数据访问的完全没有 JTA 的事务划分,如果你只访问一个数据库。如果你有设置通过 LocalSessionFactoryBean 类的 dataSource 属性传入 SessionFactory 的 DataSource , HibernateTransactionManager 自动暴露 Hibernate 事务作为一个 JDBC 事务。或者,您可以明确指定 DataSource 中哪些事务是需要支持通过 HibernateTransactionManager 类的 dataSource 属性暴露的。 你可以在一个容器管理的 JNDI SessionFactory 和本地定义的互相切换,而无需更改应用程序的代码。是否保持资源定义在容 器或本地应用程序中,主要取决于使用的事务策略。对比 Spring 定义的本地的 SessionFactory ,手动注册 JNDI SessionFactory 没有任何好处。部署一个通过 Hibernate JCA 连接器的 SessionFactory 来提供 Java EE 服务器的管理基础设 施的附加值,但在这之前不增加任何实际的值。 Spring 的事务支持不是绑定到一个容器中。在配置除了 JTA 以外的任何策略后,事务支持同样也能在一个独立的或测试的环 境中工作。特别是在单独的数据库事务的典型应用中。Spring 是一个轻量级的单资源本地事务支持和强大的 JTA 的替代品。 当你使用本地 EJB 无状态会话 bean 来驱动事务,你都必须要依赖 EJB 容器和 JTA,即使你只访问一个数据库,并且只使用无状 态会话 bean 通过容器管理的事务来提供声明式事务。另外,直接使用 JTA 编程需要一个 Java EE 环境。JTA 并不只涉及容器 依赖性的JTA 本身和 JNDI DataSource 实例。对于 非 Spring,JTA 驱动的 Hibernate 事务交易,您必须使用 Hibernate JCA 连 接器,或额外的Hibernate 事务代码 TransactionManagerLookup 为适当的 JVM 级别配置缓存。 15.3.6 Comparing container-managed and locally defined resources 比较容器管理 和本地定义的资源 Spring Framework 4.x Reference Documentation 中文翻译 15715.3. Hibernate Spring 驱动事务可以与本地定义的 Hibernate SessionFactory 和本地的JDBC DataSource 很好的工作,如果他们访问一个数 据库。因此你只需要使用 Spring 的 JTA 事务策略,在当你有分布式事务的需求的时候。JCA 连接器需要特定容器部署步骤, 显然首先需要的是 JCA 的支持。这个配置比部署一个简单的 使用本地资源定义和 Spring 驱动事务 web 应用程序需要更多的 工作。同样,你经常需要你的容器是使用的是企业版,例如,WebLogic Express, 并且是不提供 JCA。Spring 的应用程序具有本 地资源和事务跨越数据库的能力,可以在任何 Java EE web容器(没有 JTA、JCA 或 EJB )如Tomcat、Resin、甚至普通的 Jetty 中工作。此外,您可以很容易地重用这样的一个中间层在桌面应用程序或测试套件中。 从全面考虑,如果你不使用 EJB,请坚持使用本地 SessionFactory 设置和 Spring 的 HibernateTransactionManager 或 JtaTransactionManager 。你得到所有的好处,包括适当的事务 JVM 级别缓存和分布式事务, 没有容器部署的不便。JNDI 通过 JCA 连接器注册 Hibernate SessionFactory ,在与 EJB 一起使用时只是增加了值。 在一些 JTA 的非常严格的 XADataSource 实现的环境中 — 目前只在一些 WebLogic Server 和 WebSphere 版本中 — 当 Hibernate 配置时没有留意环境中的 JTA 的 PlatformTransactionManager 对象,这可能会导致 虚假告警或者异常显示在应用 服务器的日志中。这些告警或者异常显示连接访问不再有效,或 JDBC 访问不再有效,这可能是因为事务已经不再活动了。举 个例子,这是一个真实的 WebLogic 异常: java.sql.SQLException: The transaction is no longer active - status: Committed. No further JDBC access is allowed within this transaction. 要解决此警告,只需要使 Hibernate 知道 JTA PlatformTransactionManager 实例,它将同步(连同 Spring)。实现这个有两 个选项: 如果在你的应用程序上下文中你已经直接获取 JTA PlatformTransactionManager 对象(大概是从 JNDI 通 过 JndiObjectFactoryBean 或 )将它提供给,例如,Spring 的 JtaTransactionManager ,那么最简单 的方法是通过引用定义了这个 JTA PlatformTransactionManager 实例的 bean给 LocalSessionFactoryBean 指定一 个 jtaTransactionManager 的属性值。那么 Spring 就会使对象在 Hibernate 中可用。 你很有可能没有 JTA PlatformTransactionManager 实例,因为Spring 的 JtaTransactionManager 本身可以找到它。因此, 你需要配置 Hibernate 直接查找 JTA PlatformTransactionManager 。你可以在 Hibernate 配置中通过配置应用程序服务器 特定的 ransactionManagerLookup 类实现这个,正如 Hibernate 手册所描述的那样。 本节的其余部分描述了事件发生的顺序和 Hibernate 对 JTA PlatformTransactionManager 的认知。 当 Hibernate 没有配置任何 JTA PlatformTransactionManager 的认知时,当一个 JTA 事务提交时以下事件发生: JTA 事务提交。 Spring 的 JtaTransactionManager 与 JTA 事务同步时,通过 JTA 事务管理执行一个 afterCompletion 的回调。 在其他活动中,从 Spring 到 Hibernate 的同步可以触发回调,通过Hibernate 的 afterTransactionCompletion 回调(用 于清除 Hibernate 缓存),随后的是一个显式 close() 调用在 Hibernate Session,,导致 Hibernate 试图 close() JDBC 连 接。 在某些环境中,这个 Connection.close() 调用然后触发警告或错误,因为应用程序服务器不再认为 Connection 是可用的,因 为事务已经提交了。 当Hibernate 配置了 JTA PlatformTransactionManager 的认知,当一个JTA事务提交,以下事件发生: JTA 事务准备提交。 Spring 的 JtaTransactionManager 跟 JTA 事务是同步的,所以通过 JTA 事务管理器的 beforeCompletion 回调来执行事务 的回调。 Spring 感知到 Hibernate 本身与 JTA 事务是同步的,并且行为不同于在前面的场景。假设需要 Hibernate Session 关闭, 那么 Spring将会关闭它。 JTA 事务提交。 15.3.7 Spurious application server warnings with Hibernate 在 Hibernate 中的虚假 应用服务器告警 Spring Framework 4.x Reference Documentation 中文翻译 15815.3. Hibernate Hibernate 与 JTA 事务是同步的,所以通过 JTA 事务管理器的 beforeCompletion 回调来执行事务的回调,并能正确清楚其 缓存。 Spring Framework 4.x Reference Documentation 中文翻译 15915.3. Hibernate Spring 支持标准的 JDO 2.0 和 2.1 API 的数据访问策略,按照与 Hibernate 同样的支持方式。相应的集成类驻留 在 org.springframework.orm.jdo 包。 Spring提供 LocalPersistenceManagerFactoryBean 类允许您在一个 Spring 应用上下文定义了一个局部的 JDO 的 PersistenceManagerFactory : 另外,你可以通过一个 PersistenceManagerFactory 实现类的的实例化来设置 PersistenceManagerFactory 。一个 JDO 的 PersistenceManagerFactory 实现类遵循 JavaBean 模式,就像一个JDBC DataSource 的实现类,这是在 Spring 里配置使 用是非常合适的。这种设置方式通常支持一个 Spring 定义的JDBC DataSource ,传递给 connectionFactory 。例如,对于开 源的 JDO 实现DataNucleus(原名 JPOX )(http://www.datanucleus.org/),下面是 PersistenceManagerFactory 实现的 XML 配置: 也可以在 Java EE 应用服务的 JNDI 环境中 设置 JDO PersistenceManagerFactory ,通常是通过 JCA 连接器提供包含 JDO 的实现。Spring 的标准中 JndiObjectFactoryBean 或 可以用来检索和暴露比 如 PersistenceManagerFactory 。然而,在 EJB 上下文 之外,没有真正的存在于在 JNDI 中保持 PersistenceManagerFactory :只 选择这样的一个设置是一个很好的理由。请参见15.3.6“比较容器管理和本地定义的资源”讨论;那里的论点适用于JDO。 利用注入的 PersistenceManagerFactory ,也可以直接利用平常的JDO API来写 DAO,而无需 Spring 的依赖。以下是相应的 DAO 实现的一个例子: public class ProductDaoImpl implements ProductDao { private PersistenceManagerFactory persistenceManagerFactory; public void setPersistenceManagerFactory(PersistenceManagerFactory pmf) { 15.4 JDO 15.4.1 PersistenceManagerFactory setup 设置 15.4.2 Implementing DAOs based on the plain JDO API 基于平常 JDO API 的 DAO 的实现 Spring Framework 4.x Reference Documentation 中文翻译 16015.4. JDO this.persistenceManagerFactory = pmf; } public Collection loadProductsByCategory(String category) { PersistenceManager pm = this.persistenceManagerFactory.getPersistenceManager(); try { Query query = pm.newQuery(Product.class, "category = pCategory"); query.declareParameters("String pCategory"); return query.execute(category); } finally { pm.close(); } } } 因为上面的 DAO 依赖注入模式,它适合在 Spring 容器中,就像在Spring 的 JdoTemplate 中编码: 这样的 DAO 主要的问题是,他们总是从工厂获得一个新的 PersistenceManager 。为了访问 Spring 管理的事务 PersistenceManager ,需要定义一个 TransactionAwarePersistenceManagerFactoryProxy (包含在Spring 中)在你的目标 PersistenceManagerFactory 面前,然后传递一个那个代理的引用到你的 DAO,如下面的示例: 你的数据访问代码将收到一个来自 PersistenceManagerFactory.getPersistenceManager() 调用的事务性 的 PersistenceManager (如果有)的方法。后者的方法的调用会通过代理,在从从工厂获得一个新的之前它首先检查当前事 务性的 PersistenceManager 。由于 事务性的 PersistenceManager ,任何 close() 的调用将会被忽略。 如果你的数据访问代码总是运行在一个活跃的事务中(或至少与活跃的事务同步),它会安全的忽略 PersistenceManager.close() 的调用。这样整个 finally 的块,可以让你的 DAO 实现更加简洁: public class ProductDaoImpl implements ProductDao { private PersistenceManagerFactory persistenceManagerFactory; public void setPersistenceManagerFactory(PersistenceManagerFactory pmf) { this.persistenceManagerFactory = pmf; } public Collection loadProductsByCategory(String category) { PersistenceManager pm = this.persistenceManagerFactory.getPersistenceManager(); Query query = pm.newQuery(Product.class, "category = pCategory"); query.declareParameters("String pCategory"); return query.execute(category); } Spring Framework 4.x Reference Documentation 中文翻译 16115.4. JDO } 由于这样 DAO 依来活动的事务,所有建议您通过关闭 TransactionAwarePersistenceManagerFactoryProxy 的 allowCreate 标签 来强制激活事务: 这种 DAO 风格的主要优势是,它只依赖于 JDO API;不需要引进任何的Spring 类。从非侵入性的角度来说更吸引人,并且对 于 JDO 开发人员来说可能会觉得更自然。 然而,DAO 抛出平常的 JDOException (未检查的,因此不需要声明或捕获),这意味着调用者只能将异常当做是致命的,除非你想 依靠 JDO 的异常结构。捕捉乐观锁失败等特殊原因是不可能,除非把调用者与实现策略相关联。取消这交易可能会更容易受 应用程序接受,因为基于 JDO 和/或 不需要任何特殊的异常处理。 总之,你可以根据平常的 JDO API 生产 DAO ,他们仍然可以参与 Spring管理事务。这策略会可能会吸引你如果你已经熟悉了 JDO。然而,这样的DAO 抛出平常的 JDOException ,您必须显式地转换为 Spring 的 DataAccessException (如果需要)。 如果你还没有看过 12.5. Declarative transaction management 声明式事务管理强烈建议你看下,获取更多Spring 声明式事务 的支持 执行服务的事务操作,使用 Spring 常见的声明式事务功能,举例: 15.4.3 Transaction management 事务管理 Spring Framework 4.x Reference Documentation 中文翻译 16215.4. JDO JDO 需要一个活动的事务来修改持久化的对象。非事务性的刷新概念并不存在于 JDO,相对于 Hibernate。为此,你需要为 特定的环境设置选择的JDO 的实现。具体来说,你需要设置明确的 JTA 同步,来检测一个活跃的JTA 事务本身。这对于 Spring 的 JdoTransactionManager 执行的本地事务来说是没有必要的,但有必要参与 JTA 事务,不管是由 Spring JtaTransactionManager 驱动 还是 EJB CMT 和普通的 JTA。 JdoTransactionManager 能够使 JDO 事务 JDBC 访问代码f访问同一个JDBC DataSource ,提供注册的 JdoDialect 支持底层 的 JDBC Connection 检索。这是默认情况下基于JDBC 的 JDO 2.0实现 作为一个高级功能, JdoTemplate 和 JdoTransactionManager 支持自定义 JdoDialect 可以传递到 JdoDialect 的 bean 属性。在 这个场景中,DAO 不接受 PersistenceManagerFactory 的引用,而是一个完整的 JdoTemplate 实例(例如,传递到 JdoDaoSupport 的 属性 JdoTemplate 中)。使用 JdoDialect 实现,您可以启用 Spring 的高级特性支持,通常特定于供应商的方式: 应用于特定的事务语义,如自定义隔离级别或事务超时 检索事务性的 JDBC Connection ,用来暴露基于 JDBC 的 DAO 应用查询超时,自动从 Spring 管理事务超时进行计算 及时刷新 PersistenceManager ,使事务变化对于基于 JDBC 的数据访问代码可见 从 JDOExceptions 向 Spring DataAccessExceptions 的高级转换 查看 JdoDialect 的 javadocs 获取更多如果使用 Spring JDO 的细节 15.4.4 JdoDialect Spring Framework 4.x Reference Documentation 中文翻译 16315.4. JDO Spring JPA,存在与 org.springframework.orm.jpa 包,提供方便的对于 Java Persistence API 的类似于 Hibernate 或者 JDO 的支持,为了解底层的实现,提供额外的功能。 Spring JPA 提供三种方式来设置 JPA EntityManagerFactory 用于应用程序实现实体的管理。 只在简单部署环境中,比如独立的应用程序和集成测试才使用该选项 LocalEntityManagerFactoryBean 创建了一个仅使用 JPA 访问数据适合部署在简单环境下的应用程序的 EntityManagerFactory 。工厂 bean 使用 JPA PersistenceProvider 自动检测机制(根据 JPA 的Java SE 引导),在大多数情 况下,需要指定唯一持久单元名称: 这种形式的 JPA 的部署是最简单和最有限的。你不能引用现有的 JDBC DataSource 的 bean 的定义,并且不支持全局事务 的存在。此外,织入(字节码转换)持久化类是提供者特定的,往往需要一个特定的 JVM 代理在启动时指定。此选项仅适用 于为 JPA 规范设计的独立的应用程序和测试环境。 当部署在 Java EE 5 服务器中使用该选项,查看你的服务器的文档来获知如何部署自定义的 JPA 提供者 在你的服务器中, 允许不同于服务器默认的提供者。 从 JNDI 中获得 EntityManagerFactory (举例 在 Java EE 5 环境中),只需简单配置 XML: 这个动作指定标准的 Java EE 5 的引导: Java EE服务器自动检测持久单元(实际上, META-INF/persistence.xml 文件在应 用的 jar 中)和在Java EE部署描述符中的 persistence-unit-ref 的实体(例如,web.xml)并为这些定义环境命名上下文的 位置。 在这种情况下,整个持久化单元的部署,包括织入(字节码转换)持久化类,到 Java EE 服务器。JDBC DataSource 是通过 JNDI 位置定义在META-INF/persistence.xml文件中。EntityManager 事务集成在服务器的 JTA 子系统中。Spring 只是使用获 得的 EntityManagerFactory ,通过依赖注入传递给应用程序对象,并且为持久单元管理事务,通常是通过 JtaTransactionManager 。 如果多个持久单元中使用相同的应用程序, JNDI检索的持久单元的 bean 名称应与持久单元的名称匹配,应用程序引用它 们,比如,在 @PersistenceUnit 和 @PersistenceContext 注解。 15.5 JPA 15.5.1 Three options for JPA setup in a Spring environment 三种设置选项 LocalEntityManagerFactoryBean Obtaining an EntityManagerFactory from JNDI 从 JNDI 中获得 EntityManagerFactory Spring Framework 4.x Reference Documentation 中文翻译 16415.5. JPA 在基于 Spring 的使用 JPA 全功能的应用环境中,使用该选项。这个包含了 web 容器你比如 Tomcat 作为具有复杂的持续性 要求的单独的应用和集成测试 LocalContainerEntityManagerFactoryBean 给 EntityManagerFactory 完全控制配置和按需定制细粒度的适合的环 境。 LocalContainerEntityManagerFactoryBean 创建基于 persistence.xml 文件 的 PersistenceUnitInfo 的实例,提 供 dataSourceLookup 的策略,指定 loadTimeWeaver 。因此可以在 JNDI 外部使用自定义数据源和控制编织过程。下面的示例显 示了一个典型的定义 LocalContainerEntityManagerFactoryBean 的 bean: 下面展示常见的 persistence.xml : META-INF/orm.xml 快捷表明应该出现未扫描的注解的实体类。一个明确的 true 值指定 true 也意味着没有扫描。 false d 触发扫描;然而,它是建议干脆省略 exclude-unlisted-classes 元素如果你想扫描产生的实体类。 使用 LocalContainerEntityManagerFactoryBean 是最强大的 JPA 设置选项,允许丰富的在应用中本地配置。它支持连接到现有 的 JDBC DataSource ,支持 包括 本地和全局的事务,等等。然而,它还对运行时环境的有特殊的需求,比如需要 weaving- capable(可织入的)的类载入器,当持久性提供者要求字节码转换时。 此选项可能 Java EE 5 服务器中内置 JPA 功能冲突。在一个完整的 Java EE 5 的环境下,考虑从 JNDI 获取你 的 EntityManagerFactory 。另外, LocalContainerEntityManagerFactoryBean 定义中指定一个自定义 persistenceXmlLocation ,例 如, META-INF/my-persistence.xml ,并且只包含一个描述符,这个名字在你的应用程序 jar 文件。因为 Java EE 5 服务器只查 找默认 META-INF/persistence.xml 文件,它忽略了这些自定义持久性单元,从而避免与 Spring 驱动的 JPA 预先设置冲突。(例如, 这适用于 Resin 3.1)。 什么时候需要载入时织入? 不是所有的 JPA 提供者需要 JVM 代理;Hibernate 就是这样的一个例子。如果你的提供者不需要一个代理或你有其他选择,如 应用增强在构建时通过一个自定义的编译器或一个 ant 任务,此时不应使用载入时织入。 LoadTimeWeaver 接口是一个 Spring 类,允许将 JPA ClassTransformer 实例插入一个特定的方式,这取决于环境是 web 容器或应 用程序服务器。通过一个代理来挂钩 ClassTransformers 通常是无效的。代理工作在整个虚拟机并检查每一个加载类,通常是 在生产服务器环境中不受欢迎的。 Spring 提供了许多 LoadTimeWeaver 各种环境的实现,允许 ClassTransformer 实例仅适用于每个类装入器,而不是每个 VM。 参考 AOP 章节“Spring配置”了解关于 LoadTimeWeaver 实现及其设置,包括泛型或定制各种平台(如 Tomcat、WebLogic、 GlassFish、Resin 和JBoss)。 LocalContainerEntityManagerFactoryBean Spring Framework 4.x Reference Documentation 中文翻译 16515.5. JPA 如上述所述部分,您可以配置一个context-wide(宽泛上下文的) LoadTimeWeaver 使用 context:load-time-weaver 元素中 的 @EnableLoadTimeWeaving 注释。这样一个全球织入是所有 JPA LocalContainerEntityManagerFactoryBeans 自动捕捉到。这是 设置加载时织入的首选方法,能自动识别出平台(WebLogic, GlassFish, Tomcat, Resin, JBoss 或者 VM 代理)和自动传播的织 入到所有可织入的 bean 中: ... 不过,如果需要,可以手动通过 loadTimeWeaver属性 指定一个专门的织入: 无论 LTW 如何配置,使用这种技术,JPA 应用程序依赖于器可以运行在目标平台(例:Tomcat)而不需要代理的基础设施。这是非 常重要的,尤其是当托管的应用程序依赖于不同的 JPA 实现,因为 JPA 转换器只在类装入器级别,因此彼此是隔离。 对于依赖于多个持久单元的位置的应用程序,在类路径中,存储在不同的JAR 中,例如,Spring 提 供 PersistenceUnitManager 作为中央存储库,以避免持久单元的发现过程,它可以是昂贵的。默认的实现允许多个位置被指 定,稍后被通过持久单元名称检索。(默认情况下,路径搜索的的是META-INF/persistence.xml 文件。) org/springframework/orm/jpa/domain/persistence-multi.xml classpath:/my/package/**/custom-persistence.xml classpath*:META-INF/persistence.xml 默认的实现允许的自定义 PersistenceUnitInfo 实例,在他们传入 JPA 提供者之前,声明通过它的属性,影响所有的单元, 或以编程方式,通过 PersistenceUnitPostProcessor ,允许持久单元的选择。如果没有指定一个 PersistenceUnitManager , 由 LocalContainerEntityManagerFactoryBean 内部创建和使用。 虽然 EntityManagerFactory 实例是线程安全的 , 但 EntityManager 不是。注入的 JPA EntityManager 的行为像一个 从应用 服务器的 JNDI 环境中通过 JPA 规范定义的 EntityManager 。它代表所有调用当前事务 EntityManager ,如果是的话;否 则,它在每次操作时返回新创建的 EntityManager ,使其线程安全。 Dealing with multiple persistence units 处理多个持久单元 15.5.2 Implementing DAOs based on plain JPA 基于平常 JPA的 DAO 的实现 Spring Framework 4.x Reference Documentation 中文翻译 16615.5. JPA 通过注入 EntityManagerFactory 或 EntityManager ,对于编写平常 JPA 代码对 Spring 没有任何依赖。 Spring 可以理 解 @PersistenceUnit 和 @PersistenceContext 和注解在字段和方法层面,如果启动 PersistenceAnnotationBeanPostProcessor 的 话。普通的JPA DAO实现使用 @PersistenceUnit 注解可能看起来像这样: public class ProductDaoImpl implements ProductDao { private EntityManagerFactory emf; @PersistenceUnit public void setEntityManagerFactory(EntityManagerFactory emf) { this.emf = emf; } public Collection loadProductsByCategory(String category) { EntityManager em = this.emf.createEntityManager(); try { Query query = em.createQuery("from Product as p where p.category = ?1"); query.setParameter(1, category); return query.getResultList(); } finally { if (em != null) { em.close(); } } } } 上面的 DAO 没有依赖 Spring ,但 任然非常符合 Spring 应用的上下文。此外,该 DAO 充分利用 EntityManagerFactory 默认 注解: 作为一种明确替代定义 PersistenceAnnotationBeanPostProcessor ,考虑使用 Spring context:annotation-config 在你的应用 程序环境配置。这样做自动注册所有的 Spring 基于注释的配置标准处理器,包括 CommonAnnotationBeanPostProcessor 等等。 这样的 DAO 的主要的问题是,它总是通过工厂创建一个新的 EntityManager 。你可以请求一个事务 EntityManager (也被称 为“共享 EntityManager ”因为它是一个共享的,线程安全的代理在实际事务 EntityManager 中)被注入而不是工厂来避免这 种情况: public class ProductDaoImpl implements ProductDao { @PersistenceContext private EntityManager em; public Collection loadProductsByCategory(String category) { Query query = em.createQuery("from Product as p where p.category = :category"); Spring Framework 4.x Reference Documentation 中文翻译 16715.5. JPA query.setParameter("category", category); return query.getResultList(); } } @PersistenceContext 注解有个可选属性 type , 默认值是 PersistenceContextType.TRANSACTION 。默认的是你需要接收共享 的 EntityManager 代理。 PersistenceContextType.EXTENDED ,是一个完全不同的事情,这个结果对 EntityManager 的扩展,它不 是线程安全的,因此不能用于并发访问的组件如 Spring 管理单例 bean。扩展的 EntityManager 只能用在有状态的组件,例 如,驻留在一个会话上,这样EntityManager 的生命周期不依赖于当前事务,而是完全取决于应用程序。 方法和字段级别的注入 注释表明依赖注入(如 @PersistenceUnit 和 @PersistenceContext )可应用于类中的字段或方法,因此表现方法级别的注入 和字段级别的注入。字段级别的注入是简洁和容易使用而方法级别允许进一步处理注入的依赖。在这两种情况下的成员可见 性(公共,保护,私人)不要紧。 那类级别的注入呢? 在 Java EE 5 平台,它们是用来声明依赖而不是资源注入 注入 EntityManager 是 Spring 管理的(意识到正在进行的事务)。需要注意的是,尽管新的 DAO 实现使用一个 EntityManager 方法注入而不是一个 EntityManagerFactory ,在应用程序上下文的 XML 注释的用法无需改变。 这种 DAO 风格的主要优点是,它不仅取决于 Java Persistence API;(Java 持久性API),而无需引进任何 Spring 的类。此 外,作为 JPA 注释更容易理解,注解可以被 Spring 容器自动应用。这是从非侵袭性的的角度看很具有吸引力,对于 JPA 的 开发人员来说可能感觉更自然。 如果你还没有看过 12.5. Declarative transaction management 声明式事务管理强烈建议你看下,获取更多Spring 声明式事务 的支持 执行服务的事务操作,使用 Spring 常见的声明式事务功能,举例: 15.5.3 Transaction Management 事务管理 Spring Framework 4.x Reference Documentation 中文翻译 16815.5. JPA Spring 的 JPA 允许配置 JpaTransactionManager 来暴露 JPA 事务给 JDBC 访问代码从而能够访问同一个 JDBC DataSource ,提供注册 JpaDialect 支持底层的 JDBC Connection 检索。开箱即用,Spring 提供了 TopLink ,Hibernate 和 OpenJPA 的 JPA 实现的方言。请参阅下一节 JpaDialect 机制。 作为一个高级功能 JpaTemplate , JpaTransactionManager 和 AbstractEntityManagerFactoryBean 子类支持自定义 JpaDialect,传 递到 JpaDialect bean 属性。在这种情况下,DAO 未得到 EntityManagerFactory 的引用,而是一个完整的 JpaTemplate 实例(例 如,传递到 JpaDaoSupport 的 JpaTemplate 属性)。 JpaDialect 实现可以使一些 Spring 支持的高级功能,通常取决于特定供应商 的方式: 应用特定的事务语义,如自定义隔离级别或事务超时) 检索事务暴露于基于 JDBC 的 DAO 的 JDBC Connection ) PersistenceExceptions 到 Spring DataAccessExceptions 的高级转换 这对于特殊事务语义和高级的异常转换来说是非常有价值的。默认实现使用( DefaultJpaDialect )不提供任何特殊功能,如果需 要上面的功能,你必须指定适当的方言。 查看 JpaDialect 的 javadocs 获取更多如果使用 Spring JPA 的细节 15.5.4 JpaDialect Spring Framework 4.x Reference Documentation 中文翻译 16915.5. JPA Spring Framework 4.x Reference Documentation 中文翻译 17016. Marshalling XML using O/X Mappers Spring Framework 4.x Reference Documentation 中文翻译 17116.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 17216.2. Marshaller and Unmarshaller Spring Framework 4.x Reference Documentation 中文翻译 17316.3. Using Marshaller and Unmarshaller Spring Framework 4.x Reference Documentation 中文翻译 17416.4. XML Schema-based Configuration Spring Framework 4.x Reference Documentation 中文翻译 17516.5. JAXB Spring Framework 4.x Reference Documentation 中文翻译 17616.6. Castor Spring Framework 4.x Reference Documentation 中文翻译 17716.7. XMLBeans Spring Framework 4.x Reference Documentation 中文翻译 17816.8. JiBX Spring Framework 4.x Reference Documentation 中文翻译 17916.9. XStream Spring Framework 4.x Reference Documentation 中文翻译 18017.9. Using themes Spring Framework 4.x Reference Documentation 中文翻译 18117. Web MVC framework Spring Framework 4.x Reference Documentation 中文翻译 18217.1. Introduction to Spring Web MVC framework Spring Framework 4.x Reference Documentation 中文翻译 18317.2. The DispatcherServlet Spring Framework 4.x Reference Documentation 中文翻译 18417.3. Implementing Controllers Spring Framework 4.x Reference Documentation 中文翻译 18517.4. Handler mappings Spring Framework 4.x Reference Documentation 中文翻译 18617.5. Resolving views Spring Framework 4.x Reference Documentation 中文翻译 18717.6. Using flash attributes Spring Framework 4.x Reference Documentation 中文翻译 18817.7. Building URIs Spring Framework 4.x Reference Documentation 中文翻译 18917.8. Using locales Spring Framework 4.x Reference Documentation 中文翻译 19017.10. Spring’s multipart (file upload) support Spring Framework 4.x Reference Documentation 中文翻译 19117.11. Handling exceptions Spring Framework 4.x Reference Documentation 中文翻译 19217.12. Web Security Spring Framework 4.x Reference Documentation 中文翻译 19317.13. Convention over configuration support Spring Framework 4.x Reference Documentation 中文翻译 19417.14. ETag support Spring Framework 4.x Reference Documentation 中文翻译 19517.15. Code-based Servlet container initialization Spring Framework 4.x Reference Documentation 中文翻译 19617.16. Configuring Spring MVC Spring Framework 4.x Reference Documentation 中文翻译 19718. View technologies Spring Framework 4.x Reference Documentation 中文翻译 19818.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 19918.2. JSP & JSTL Spring Framework 4.x Reference Documentation 中文翻译 20018.3. Tiles Spring Framework 4.x Reference Documentation 中文翻译 20118.4. Velocity & FreeMarker Spring Framework 4.x Reference Documentation 中文翻译 20218.5. XSLT Spring Framework 4.x Reference Documentation 中文翻译 20318.6. Document views (PDF/Excel) Spring Framework 4.x Reference Documentation 中文翻译 20418.7. JasperReports Spring Framework 4.x Reference Documentation 中文翻译 20518.8. Feed Views Spring Framework 4.x Reference Documentation 中文翻译 20618.9. XML Marshalling View Spring Framework 4.x Reference Documentation 中文翻译 20718.10. JSON Mapping View Spring Framework 4.x Reference Documentation 中文翻译 20818.11. XML Mapping View Spring Framework 4.x Reference Documentation 中文翻译 20919. Integrating with other web frameworks Spring Framework 4.x Reference Documentation 中文翻译 21019.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 21119.2. Common configuration Spring Framework 4.x Reference Documentation 中文翻译 21219.3. JavaServer Faces 1.2 Spring Framework 4.x Reference Documentation 中文翻译 21319.4. Apache Struts 2.x Spring Framework 4.x Reference Documentation 中文翻译 21419.5. Tapestry 5.x Spring Framework 4.x Reference Documentation 中文翻译 21519.6. Further Resources Spring Framework 4.x Reference Documentation 中文翻译 21620. Portlet MVC Framework Spring Framework 4.x Reference Documentation 中文翻译 21720.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 21820.2. The DispatcherPortlet Spring Framework 4.x Reference Documentation 中文翻译 21920.3. The ViewRendererServlet Spring Framework 4.x Reference Documentation 中文翻译 22020.4. Controllers Spring Framework 4.x Reference Documentation 中文翻译 22120.5. Handler mappings Spring Framework 4.x Reference Documentation 中文翻译 22220.6. Views and resolving them Spring Framework 4.x Reference Documentation 中文翻译 22320.7. Multipart (file upload) support Spring Framework 4.x Reference Documentation 中文翻译 22420.8. Handling exceptions Spring Framework 4.x Reference Documentation 中文翻译 22520.9. Annotation-based controller configuration Spring Framework 4.x Reference Documentation 中文翻译 22620.10. Portlet application deployment Spring Framework 4.x Reference Documentation 中文翻译 22721. WebSocket Support Spring Framework 4.x Reference Documentation 中文翻译 22821.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 22921.2. WebSocket API Spring Framework 4.x Reference Documentation 中文翻译 23021.3. SockJS Fallback Options Spring Framework 4.x Reference Documentation 中文翻译 23121.4. STOMP Over WebSocket Messaging Architecture Spring Framework 4.x Reference Documentation 中文翻译 232VI. Integration Spring Framework 4.x Reference Documentation 中文翻译 23322. Remoting and web services using Spring Spring Framework 4.x Reference Documentation 中文翻译 23422.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 23522.2. Exposing services using RMI Spring Framework 4.x Reference Documentation 中文翻译 23622.3. Using Hessian or Burlap to remotely call services via HTTP Spring Framework 4.x Reference Documentation 中文翻译 23722.4. Exposing services using HTTP invokers Spring Framework 4.x Reference Documentation 中文翻译 23822.5. Web services Spring Framework 4.x Reference Documentation 中文翻译 23922.6. JMS Spring Framework 4.x Reference Documentation 中文翻译 24022.7. AMQP Spring Framework 4.x Reference Documentation 中文翻译 24122.8. Auto-detection is not implemented for remote interfaces Spring Framework 4.x Reference Documentation 中文翻译 24222.9. Considerations when choosing a technology Spring Framework 4.x Reference Documentation 中文翻译 24322.10. Accessing RESTful services on the Client Spring Framework 4.x Reference Documentation 中文翻译 24423. Enterprise JavaBeans (EJB) integration Spring Framework 4.x Reference Documentation 中文翻译 24523.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 24623.2. Accessing EJBs Spring Framework 4.x Reference Documentation 中文翻译 24723.3. Using Spring’s EJB implementation support classes Spring Framework 4.x Reference Documentation 中文翻译 24824. JMS (Java Message Service) Spring Framework 4.x Reference Documentation 中文翻译 24924.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 25024.2. Using Spring JMS Spring Framework 4.x Reference Documentation 中文翻译 25124.3. Sending a Message Spring Framework 4.x Reference Documentation 中文翻译 25224.4. Receiving a message Spring Framework 4.x Reference Documentation 中文翻译 25324.5. Support for JCA Message Endpoints Spring Framework 4.x Reference Documentation 中文翻译 25424.6. Annotation-driven listener endpoints Spring Framework 4.x Reference Documentation 中文翻译 25524.7. JMS Namespace Support Spring Framework 4.x Reference Documentation 中文翻译 25625. JMX Spring Framework 4.x Reference Documentation 中文翻译 25725.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 25825.2. Exporting your beans to JMX Spring Framework 4.x Reference Documentation 中文翻译 25925.3. Controlling the management interface of your beans Spring Framework 4.x Reference Documentation 中文翻译 26025.4. Controlling the ObjectNames for your beans Spring Framework 4.x Reference Documentation 中文翻译 26125.5. JSR-160 Connectors Spring Framework 4.x Reference Documentation 中文翻译 26225.6. Accessing MBeans via Proxies Spring Framework 4.x Reference Documentation 中文翻译 26325.7. Notifications Spring Framework 4.x Reference Documentation 中文翻译 26425.8. Further Resources Spring Framework 4.x Reference Documentation 中文翻译 26526. JCA CCI Spring Framework 4.x Reference Documentation 中文翻译 26626.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 26726.2. Configuring CCI Spring Framework 4.x Reference Documentation 中文翻译 26826.3. Using Spring’s CCI access support Spring Framework 4.x Reference Documentation 中文翻译 26926.4. Modeling CCI access as operation objects Spring Framework 4.x Reference Documentation 中文翻译 27026.5. Transactions Spring Framework 4.x Reference Documentation 中文翻译 27127. Email Spring Framework 4.x Reference Documentation 中文翻译 27227.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 27327.2. Usage Spring Framework 4.x Reference Documentation 中文翻译 27427.3. Using the JavaMail MimeMessageHelper Spring Framework 4.x Reference Documentation 中文翻译 27528. Task Execution and Scheduling Spring Framework 4.x Reference Documentation 中文翻译 27628.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 27728.2. The Spring TaskExecutor abstraction Spring Framework 4.x Reference Documentation 中文翻译 27828.3. The Spring TaskScheduler abstraction Spring Framework 4.x Reference Documentation 中文翻译 27928.4. Annotation Support for Scheduling and Asynchronous Execution Spring Framework 4.x Reference Documentation 中文翻译 28028.5. The Task Namespace Quartz使用 Trigger , Job 和 JobDetail 来实现各种调度任务。Quartz的基础概念可以查看http://quartz-scheduler.org。为了 方便,Spring提供了在Spring基础应用下简单使用Quartz的数个类。 Quartz JobDetail 对象包含了执行一个工作任务的所有必要信息。Spring提供 JobDetailFactoryBean 以XML格式配置Bean样 式的属性。让我们来看一个例子: 工作任务细节配置包含了执行的所有需要的信息( ExampleJob )。timeout是在工作任务数据以键值形式被指定。工作任务数 据键值可以通过 JobExecutionContext 工作执行上下文获取(在执行期间传递),但是 JobDetail 也是通过工作实例被数据映 射的属性来得到它的属性值。所以在这个例子中,如果 ExampleJob 包含了一个名称为 timeout 的bean属性, JobDetail 将会 自动获取到: package example; public class ExampleJob extends QuarztJobBean { private int timeout; /** * Setter called after the ExampleJob is instantiated * with the value from the JobDetailFactoryBean(5) */ public void setTimeout(int timeout) { this.timeout = timeout; } protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException { // do the actual work } } 通过工作数据键值配置的所有附件属性也都是可用的。 使用 name 和 group 属性,可以分别改变工作的名称和组。工作的名称默认是匹配 JobDetailFactoryBean 的名称(在上面 的例子中,就是 exampleJob ) 经常需要调用特定对象的方法。使用 MethodInvokingJobDetailFactoryBean 可以实现这一点: 28.6 Using the Quartz Scheduler使用Quartz任务调度 28.6.1 Using the JobDetailFactoryBean 28.6.2 Using the JobDetailFactoryBean Spring Framework 4.x Reference Documentation 中文翻译 28128.6. Using the Quartz Scheduler 上面的例子将会调用 exampleBusinessObject 对象的 doIt 方法: public class ExampleBusinessObject { // properties and collaborators public void doIt() { // do the actual work } } 使用 MethodInvokingJobDetailFactoryBean ,不需要去创建一个仅仅实现调用方法的主工作任务,只需创建真正业务逻辑对象 和关注对象实现的细节。 Quartz工作任务默认是无状态的,导致的结果工作任务之间会相互干扰。如果给同一个 JobDetail 指定两个触发器,可能会 出现在第一个任务完成之前,第二个任务就要开始了。如果 JobDetail 类实现了 Stateful 接口,这种情况就不会发生。在第 一个任务完成之前第二个任务将不会开始。为了使任务通过 MethodInvokingJobDetailFactoryBean 不并发,设置 concurrent 标 志为 false 。 默认的工作任务是在并发形式下执行的 我们已经创建了工作任务和任务的实现。也有方便的bean来调用指定的对象方法。我们仍然需要这些工作任务自己进行调 度。使用触发器和 SchedulerFactoryBean 来完成。Quartz实现了几个触发器,Spring提供两个方便的Quartz FactoryBean 实 现: CronTriggerFactoryBean 和 SimpleTriggerFactoryBean 。 触发器是需要被安排调用的。Spring提供SchedulerFactoryBean使触发器做可以设置的属性暴露出 来。 SchedulerFactoryBean 使用触发器来安排调用工作任务。 下面是两个例子: 现在我们已经设置了两个触发器,一个每隔50秒延迟10秒启动一个次和一个每天在上6点执行。最后我们需要设 置 SchedulerFactoryBean : 28.6.3 Wiring up jobs using triggers and the SchedulerFactoryBean Spring Framework 4.x Reference Documentation 中文翻译 28228.6. Using the Quartz Scheduler SchedulerFactoryBean 更多的可设置属性,例如工作任务实现使用的calendars,Quartz自定义的属性等等。查 看 SchedulerFactoryBean 的javadocs了解更多信息。 Spring Framework 4.x Reference Documentation 中文翻译 28328.6. Using the Quartz Scheduler Spring Framework 4.x Reference Documentation 中文翻译 28429. Dynamic language support Spring Framework 4.x Reference Documentation 中文翻译 28529.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 28629.2. A first example Spring Framework 4.x Reference Documentation 中文翻译 28729.3. Defining beans that are backed by dynamic languages Spring Framework 4.x Reference Documentation 中文翻译 28829.4. Scenarios Spring Framework 4.x Reference Documentation 中文翻译 28929.5. Bits and bobs Spring Framework 4.x Reference Documentation 中文翻译 29029.6. Further Resources Spring Framework 4.x Reference Documentation 中文翻译 29130. Cache Abstraction Spring Framework 4.x Reference Documentation 中文翻译 29230.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 29330.2. Understanding the cache abstraction Spring Framework 4.x Reference Documentation 中文翻译 29430.3. Declarative annotation-based caching Spring Framework 4.x Reference Documentation 中文翻译 29530.4. JCache (JSR-107) annotations Spring Framework 4.x Reference Documentation 中文翻译 29630.5. Declarative XML-based caching Spring Framework 4.x Reference Documentation 中文翻译 29730.6. Configuring the cache storage Spring Framework 4.x Reference Documentation 中文翻译 29830.7. Plugging-in different back-end caches Spring Framework 4.x Reference Documentation 中文翻译 29930.8. How can I set the TTL/TTI/Eviction policy/XXX feature? Spring Framework 4.x Reference Documentation 中文翻译 300VII. Appendices Spring Framework 4.x Reference Documentation 中文翻译 30131. Migrating to Spring Framework 4.0 Spring Framework 4.x Reference Documentation 中文翻译 30232. Classic Spring Usage Spring Framework 4.x Reference Documentation 中文翻译 30332.1. Classic ORM usage Spring Framework 4.x Reference Documentation 中文翻译 30432.2. Classic Spring MVC Spring Framework 4.x Reference Documentation 中文翻译 30532.3. JMS Usage Spring Framework 4.x Reference Documentation 中文翻译 30633. Classic Spring AOP Usage Spring Framework 4.x Reference Documentation 中文翻译 30733.1. Pointcut API in Spring Spring Framework 4.x Reference Documentation 中文翻译 30833.2. Advice API in Spring Spring Framework 4.x Reference Documentation 中文翻译 30933.3. Advisor API in Spring Spring Framework 4.x Reference Documentation 中文翻译 31033.4. Using the ProxyFactoryBean to create AOP proxies Spring Framework 4.x Reference Documentation 中文翻译 31133.5. Concise proxy definitions Spring Framework 4.x Reference Documentation 中文翻译 31233.6. Creating AOP proxies programmatically with the ProxyFactory Spring Framework 4.x Reference Documentation 中文翻译 31333.7. Manipulating advised objects Spring Framework 4.x Reference Documentation 中文翻译 31433.8. Using the "autoproxy" facility Spring Framework 4.x Reference Documentation 中文翻译 31533.9. Using TargetSources Spring Framework 4.x Reference Documentation 中文翻译 31633.10. Defining new Advice types Spring Framework 4.x Reference Documentation 中文翻译 31733.11. Further resources Spring Framework 4.x Reference Documentation 中文翻译 31834. XML Schema-based configuration Spring Framework 4.x Reference Documentation 中文翻译 31934.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 32034.2. XML Schema-based configuration Spring Framework 4.x Reference Documentation 中文翻译 32135. Extensible XML authoring Spring Framework 4.x Reference Documentation 中文翻译 32235.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 32335.2. Authoring the schema Spring Framework 4.x Reference Documentation 中文翻译 32435.3. Coding a NamespaceHandler Spring Framework 4.x Reference Documentation 中文翻译 32535.4. BeanDefinitionParser Spring Framework 4.x Reference Documentation 中文翻译 32635.5. Registering the handler and the schema Spring Framework 4.x Reference Documentation 中文翻译 32735.6. Using a custom extension in your Spring XML configuration Spring Framework 4.x Reference Documentation 中文翻译 32835.7. Meatier examples Spring Framework 4.x Reference Documentation 中文翻译 32935.8. Further Resources Spring Framework 4.x Reference Documentation 中文翻译 33036. spring.tld Spring Framework 4.x Reference Documentation 中文翻译 33136.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 33236.2. the bind tag Spring Framework 4.x Reference Documentation 中文翻译 33336.3. the escapeBody tag Spring Framework 4.x Reference Documentation 中文翻译 33436.4. the hasBindErrors tag Spring Framework 4.x Reference Documentation 中文翻译 33536.5. the htmlEscape tag Spring Framework 4.x Reference Documentation 中文翻译 33636.6. the message tag Spring Framework 4.x Reference Documentation 中文翻译 33736.7. the nestedPath tag Spring Framework 4.x Reference Documentation 中文翻译 33836.8. the theme tag Spring Framework 4.x Reference Documentation 中文翻译 33936.9. the transform tag Spring Framework 4.x Reference Documentation 中文翻译 34036.10. the url tag Spring Framework 4.x Reference Documentation 中文翻译 34136.11. the eval tag Spring Framework 4.x Reference Documentation 中文翻译 34237. spring-form.tld Spring Framework 4.x Reference Documentation 中文翻译 34337.1. Introduction Spring Framework 4.x Reference Documentation 中文翻译 34437.2. the checkbox tag Spring Framework 4.x Reference Documentation 中文翻译 34537.3. the checkboxes tag Spring Framework 4.x Reference Documentation 中文翻译 34637.4. the errors tag Spring Framework 4.x Reference Documentation 中文翻译 34737.5. the form tag Spring Framework 4.x Reference Documentation 中文翻译 34837.6. the hidden tag Spring Framework 4.x Reference Documentation 中文翻译 34937.7. the input tag Spring Framework 4.x Reference Documentation 中文翻译 35037.8. the label tag Spring Framework 4.x Reference Documentation 中文翻译 35137.9. the option tag Spring Framework 4.x Reference Documentation 中文翻译 35237.10. the options tag Spring Framework 4.x Reference Documentation 中文翻译 35337.11. the password tag Spring Framework 4.x Reference Documentation 中文翻译 35437.12. the radiobutton tag Spring Framework 4.x Reference Documentation 中文翻译 35537.13. the radiobuttons tag Spring Framework 4.x Reference Documentation 中文翻译 35637.14. the select tag Spring Framework 4.x Reference Documentation 中文翻译 35737.15. the textarea tag

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 8 金币 [ 分享文档获得金币 ] 17 人已下载

下载文档

相关文档