SpringSource在上个月中旬发布了Spring 3.1的GA版本。通过InfoQ先前的一篇文章,我们了解了Spring 3.1主要的新功能,其中包括对Java 7的支持,还有环境抽象和缓存抽象。
Chris Beams是Spring框架的主要提交者,InfoQ就Spring 3.1发布的更多细节和Spring 3.2的计划对他进行了采访。
InfoQ:Spring 3.1原计划是在2011年6月底发布GA版本。为什么会推迟到现在呢?
我们原计划要为Spring容器提供完全基于Java的配置,但这种方法在试行一段时间之后,甚至能作为完整里程碑的时候,我们对这种方法进行了反思;这种方法并不能完全满足我们的设计目标。一次完整的设计迭代之后,我们把目前的方法做成了@Enable*注解。
我们很早就开始支持Servlet 3.0容器,也遇到了一些容器实现自身的问题。我们不得不和实现容器的团队一起做一些迭代,来确保实现是正确的。
不过真正的主要原因是我们有意地扩大了范围,好让3.1就包括对Java 7提供支持,而不是等到3.2再开始。这主要围绕对fork/join的支持和JDBC 4.1。我们还决定,要尽可能早地支持Hibernate 4,甚至在他们发布最终版本之前。目前我们用的是Hibernate 4的RC 7版本,实际上我们的发布版本也基于RC 7,所以Hibernate 4.0的最终版本一旦可用,Spring 3.1.1就会立即升级去支持Hibernate 4.0最终版。
另外值得一提的是,我们不想让时间追着跑,而是尽可能提供最好的版本。所以它是连续、完整的,也能保证对用户来说是真正有意义的。
InfoQ:Spring对Java 7提供了支持,这是不是能直观反映出Java 7的运用会比Java 5和Java 6更为迅速?
我认为是有可能的。Open JDK和IBM都已经发布了JDK 7,这是个好迹象。我们可以预测,选择基于OpenJDK 7的Tomcat 7是自然而然的。
我们当然希望Java 7能被迅速采用,在一定程度上,我们也希望能助它的推广和提升一臂之力。如果Spring有一个版本能为人们打开一道门,或许Java 7的推广能变得更加容易一些。
InfoQ:Spring 3.1还利用了Java 7的其他哪些功能?像try-with-resources或其他Project Coin功能使用了么?
我们一直记着这些功能,还有Java 8里的语言特性,但Spring 3.1并没有过多地利用它们。大部分新特性在针对特定API的时候都很方便,比如multi-catch、try-with-resources和switch语句支持String,而不像泛型这种语言特性会直接影响API供应商。值得注意的是,Spring 3.2将会关注JMS 2,并有可能和try-with-resources保持一致。让我们拭目以待。
InfoQ:你刚刚提到你们引入了环境抽象的概念。能给我们一个在哪里会使用它的例子么?
环境支持实际上可以分为两类:一类是属性源抽象的概念,第二类是Bean定义Profile。
就属性源来说,你要是琢磨过Java设计,就知道获取属性的方式有很多,比如系统环境变量、JVM系统属性、真正的Map或Property对象,或从数据库或键值存储里获得。但从语义上来说,这些属性都有共同点。它们基本上都是改变环境的配置属性。那属性源抽象就是个简单的SPI(服务提供者接口),其实现能为应用配置提供键值对形式的后端存储。把属性源抽象加到Spring环境里的具体做法是,由环境维护这些你能操作和查询的属性源的层次化结构。举例来说,Spring的StandardEnvironment适用于独立应用,直接使用时可以带有表示环境变量和JVM系统属性的属性源。对Web应用来说,Spring的StandardWebEnvironment会把Servlet的init-params、context-params和JNDI属性源混杂在一起。Environment已经深度集成到了整个容器和Spring的property-placeholder机制里;这个概念能提供一致的抽象,这样你就可以说:“Spring,告诉我这个属性的值”,应用也不需要知道或关心这个值从哪里来。
第二部分是Bean定义Profile,这通常能让你基于应用的部署环境(比如开发环境、测试环境、生产环境,或者相对于传统环境的云环境)有条件地注册Bean定义。所以举例来说,相对于生产环境,你可以在开发环境下使用Spring的JDBC命名空间和嵌入式数据库构建器等内容来预设一个嵌入式数据库,然后在生产环境里,应用可以从JNDI获取数据源。
过去一段时间里我们发现有很多这样的需求,目前这也能被很好地接受了。我们希望看到人们用各种方式把它利用起来。
InfoQ:本次发布的另一个重磅内容是Spring Cache。Spring Cache和Spring Data项目是怎么协调的?
Spring 3.1的缓存抽象是个SPI,主要包括需要由后端缓存提供者去实现的Cache和CacheManager接口。然后还有一些共同构成声明性编程模型的注解,比如@Cacheable、@CachePut、@CacheEvict等。
Spring Data实际上是个大型项目,是一组项目的集合,旨在利用模板类等大家熟悉的Spring机制来访问个人数据存储。这些数据存储本来有很多就适合做缓存,借助我们已经完成的集成工作,它们都可以直接使用了,比如说,GemFire或Redis都是缓存提供者,因为针对Cache和CacheManager这两个SPI,他们都提供了现成的实现。不论后端实现是什么,开发人员只需要关注@Cacheable、@CachePut等注解就可以了。
InfoQ:Spring Cache和JCache(JSR 107)有多少重叠内容?
我觉得它们是互补的,规范已经完成了,那我们肯定会为自己的缓存管理器SPI提供有一个基于JCache的实现。你可以预想到,如果接口是CacheManager,我们就会提供一个JCacheCacheManager,就和我们用Spring内核发布一个Ehcache管理器一样。真正漂亮的是,目前的SPI和Spring Data是我们自己实现的。有了JCache之后,所有供应商都会尽可能采用它,他们差不多都会去实现JCache的SPI,这会进一步提升JCache的嵌入能力,不论后端的提供者是什么。
在编程模型方面,注解有比较多的重叠,这在一定程度上是可预见的。因为两个东西在语义上就有很多重叠,在某些情况下也会使用同一个注解。所以JCache一旦完成之后,我们极有可能要对自己的注解和JCache的注解同时提供支持。Spring 2.5里我们引入了自己的@Autowired注解,这个注解同时还要支持后来被JSR-330标准化的@Inject注解,现在的情况就跟这个非常类似。
InfoQ:你们跟踪JSR 347么?你认为它对Spring Cache有影响么?
我不是那个规范和领域的专家,但根据它自身的优点来看,它肯定是有意义的。现在已经有很多不同的数据网格和分布式缓存提供者了;他们往往采用不同的方式去完成相似的事情。我们需要一个所有人都认可的规范来统一语义,这个规范姗姗来迟,JSR 347就是个很不错的选择。
鉴于JCache JSR还没全部完成,而JSR-347又是以它为基础的,所以进一步推测可能有点儿为时尚早。从Spring的角度看,JSR-347可能不需要为我们提供的内容做太多事情。我们主要是为后端存储提供一致的编程模型和简单的SPI。从JCache的角度来看,后端存储只不过是数据存储罢了。JCache和JSR-347碰巧都是分布式的,这实际上有点儿重叠。这个情况可能和Spring对事务管理的支持差不多。我们已经有了注解的方式和SPI,然后可能会出现数量不定的实现,其中之一就是JTA,但从Spring用户的角度来看,这确实没什么影响;JSR-347对Spring Cache是有影响,但从编程模型的角度来说并没有什么关系。
InfoQ:你提到Spring 3.2相关的几部分内容,比如JMS 2.0和JCache。能和我们再多分享一些计划里的内容么?
好的。在规范方面,我们正在研究JPA 2.1、Bean Validation 1.1。我们也会确保Spring和JSF 2.2能很好地协作。除此之外,还有好几个我们尚未完全确认的研究领域,但我们会继续深入研究,比如并发编程方法。对于Spring 3.1要集成一个fork/join池,我们已经提供了一些非常基本的支持,但随着fork/join等内容的引入,应用开发模型会发生什么样的变化呢?我觉得不仅仅是Spring,更大范围的社区对这个问题也都还没有答案。所以最高目标是,不光要搞明白这个问题,还要提供一些指导、给出一些示例应用等。
异步编程模型也是一样。对Java开发人员来说,Servlet 3.0里现在就有异步工具,它们本身运行得很好,但怎么从Spring等Web框架里集成它们还悬而未决。如果你有一个启用了异步功能的Servlet,请求管道里的其他Servlet组件就需要知道异步情况,所有的过滤器等也都是一样。那些Servlet组件要不要达到这个目标,并重构所有内容呢?对最终开发人员来说这意味着什么?对框架来说又如何呢?其他框架和我们所作的有哪些不同呢?
我们也想继续关注应用开发在云里会有怎样的变化。目前我们所了解的是一些PaaS提供者,它们都能正确处理那些并发访问他们平台的基于Java的负载;所以应用开发主要是基于war的部署模式和基于Servlet的应用。但有一个问题确实值得我们思考一下,就是“用云的特性来处理这些内容是否就是最好的方式呢?”
Chris也谈到,他们正在重新考虑Spring的错误报告机制,以便配置错误相关的堆栈跟踪信息能少一些,让它能和javac的输出更相似;还要找一个更为现代和易于使用的工具来替换掉CGLib代理。Spring框架的版本控制工具也会把Subversion换成Git(Hub),从3.2开始,构建系统也会从Ant/Ivy换成Gradle。
Spring 3.2的时间表相当乐观,计划会在2012年的第四季度发布,大体上会遵循上面提到的那些规范。
查看英文原文:Spring 3.1 is GA Today - Adds Java 7 Support, Environment Abstraction and Cache Abstraction