Spring 3.1 is GA Today - Adds Java 7 Support, Environment Abstraction and Cache Abstraction
SpringSource have announced the general availability of Spring 3.1 today. In a previous InfoQ article we looked at the major new features for Spring 3.1, which include Java 7 support, environment abstraction and cache abstraction.
InfoQ spoke to Chris Beams, core committer on the Spring framework, to find out more about the release, and plans for Spring 3.2.
InfoQ: Spring 3.1 was originally targeted for GA release at the end of June. What were the reasons you delayed it?
The original plan had been to provide completely Java-based configuration for the Spring container, but after quite a bit of experimentation with a first approach, and even going as far as a full milestone, we rethought it; it didn't quite meet all the design goals that we had. A full design iteration later, we landed on the current approach around @Enable* annotations.
We also had early support for Servlet 3.0 containers, and ran into problems with the implementations themselves. We had to do some iterations with the teams there, to make sure that the implementations were correct.
But really, the main reason was that we intentionally increased the scope to include Java 7 support in 3.1, instead of 3.2. That's around the fork/join support, JDBC 4.1. We also made the decision to support Hibernate 4 as early as possible, even prior to their final release. We're currently on their candidate release 7, and we have in fact shipped on that, so Spring 3.1.1 will immediately upgrade to Hibernate 4.0 final when it becomes available.
It's also worth mentioning that we don't tend to be date driven, but rather aim to deliver the best possible release. So it's about cohesiveness and completeness, and making sure that it is something that really makes sense for users.
InfoQ: Does the fact that you've brought your Java 7 support forward reflect a more rapid adoption of Java 7 than we saw with Java 5 and 6?
I think the potential is there. We've seen JDK 7 releases already from both Open JDK and IBM, which is a good sign. We certainly predict, and indeed have a hand in influencing, Tomcat 7 on OpenJDK 7 being a natural fit.
We certainly hope that the uptake will be rapid, and to some extent maybe we want to have a hand in helping to promote that and boost it. If there's a version Spring out there that opens the door for people, perhaps it becomes that much more likely.
We're certainly keeping them in mind (along with Java 8 language features as well), but there's not too much that Spring 3.1 could take advantage of here. Most of the new features, like multi-catch, try-with-resources and switching on strings are conveniences when working against a given API, as opposed to a language feature like generics, which had direct implications on API providers. It's worth noting that Spring 3.2 will have a focus on JMS 2, and there may be some natural alignment with try-with-resources there. We'll see.
InfoQ: You mentioned earlier that you've introduced the concept of environment abstraction. Can you give us examples of where that might be used?
The environment support really breaks down into two sub-categories: one is the idea of a property source abstraction, and the second is bean definition profiles.
With property sources, if you think about the Java landscape, there are all manner of places where properties can be sourced, such as system environment variables, and JVM system properties, actual Map or Property objects, from a database or key-value store. But semantically, all these things have something in common. These are basically configuration properties that change from environment to environment. The property source abstraction then, is a simple SPI [Service Provider Interface] that can be implemented against any back-end store of key/value pairs for the purposes of application configuration. How that comes together in the Spring environment, is that the environment maintains a hierarchical structure of these property sources that you can manipulate and query. For example, Spring's StandardEnvironment is suitable for standalone applications and comes out of the box with property sources representing environment variables and JVM system properties. For web applications, Spring's StandardWebEnvironment adds Servlet init-params, context-params and JNDI property sources into the mix. The Environment is deeply integrated throughout the container and in Spring's property-placeholder mechanisms; the idea is to provide one consistent abstraction, where you can say, "Spring, tell me what the value of this property is", and application code doesn't have to know or care where it came from.
The second piece is bean definition profiles, which allow you to conditionally register bean definitions, often based on the application's deployment environment (e.g. dev, test, prod, or perhaps cloud vs. traditional environment). So, for example, in the dev vs. production example you could imagine something like an embedded database, using maybe Spring's JDBC namespace and embedded database builder, that kind of thing, and then in the production one it's grabbing the datasource out of JNDI.
This is something we've seen a lot of requests for over time, and it's been pretty well-received so far. We're looking forward to seeing the various ways folks put it to use.
InfoQ: The other big headline piece in this release is Spring Cache. How does Spring Cache sit with the Spring Data project?
Spring 3.1's caching abstraction is an SPI consisting principally of the Cache and CacheManager interfaces, to be implemented against backing cache providers. And then the annotations that together form the declarative programming model, e.g. @Cacheable, @CachePut, @CacheEvict, and so on.
Spring Data is really an umbrella project, a whole collection of projects, that are designed to provide access to individual datastores using familiar Spring mechanisms, like template classes and so on. Many of those datastores are naturally suitable for caching and, thanks to the integration we've already done, it's straightforward to use, for example, GemFire or Redis as the cache provider, because they have out-of-the-box implementations of the Cache and CacheManager SPIs. Regardless of what that backing implementation is, the developer need only think about the annotations, like @Cacheable, @CachePut, etc.
InfoQ: How much overlap does Spring Cache have with JCache (JSR 107)?
They are complementary I would say and, as the spec wraps up there, we'll certainly have a JCache based implementation of our own cache manager SPI. So you can imagine that if the interface is CacheManager we'll have a JCacheCacheManager, just like we ship an Ehcache manager with Spring core. And what's really nice there is that, right now, for our own SPI and Spring Data, we implement those ourselves. With JCache out there, and naturally having as wide as possible an adoption amongst all the vendors, they'll almost certainly implement JCache's SPI, so that gives us a lot more drop-in-ability, regardless of what the back-end provider is.
On the programming model side, there's quite an overlap between the annotations, which to some degree was predictable. There's quite a bit of semantic overlap, and in some cases the same annotation name has been used. So what is very likely, once JCache is done, is that we'll have support for both our own annotations and JCache's annotations. This is quite similar to the arrangement we currently have with our own @Autowired annotations introduced in Spring 2.5 that now live alongside support for JSR-330 @Inject annotations, which were standardized later.
InfoQ: Are you also following JSR 347? Do you see that having an impact on Spring Cache?
I'm not an expert on that spec, or even the space, but on its own merits it certainly seems to make sense. We've got lots of different datagrid and distributed cache providers; they do of similar things in often different ways. It's a good candidate for a lagging spec to come along and provide some unification that everyone agrees on semantically.
Given that the JCache JSR isn't yet complete, and JSR-347 builds on top of it, it's probably a bit early to speculate much further. From Spring's perspective it probably won't have too much to do with what we're providing. We're basically providing a consistent programming model and a simple SPI for backing stores. The backing stores are, from a JCache perspective, just a datastore. The fact they happen to be distributed is a bit of an orthogonal concern. This arrangement is probably comparable to Spring's transaction management support. We've got the annotation approach there, we've got the SPI, and then any number of implementations may exist, one of which is JTA, but from a Spring user's point of view this is indeed orthogonal; it matters, but it doesn't matter from a programming model point of view.
InfoQ: You've talked about a couple of things with regards Spring 3.2, such as JMS 2.0, and JCache. What else can you tell me about what you have planned?
Well, in terms of specs, we're looking at JPA 2.1, Bean Validation 1.1. We'll also make sure that Spring plays nicely with JSF 2.2. Beyond that, we have various research areas which we don't have totally figured out, but we'll be thinking deeply on, for example concurrent programming approaches. We've provided some very basic support for integrating a fork/join pool with Spring 3.1, but how does the application development model change with things like fork/join involved? That's an unanswered question, I think, not just for Spring but for the community at large. So the highest goal would be to not only figure this out, but also provide some guidance, see some example applications, and so on.
Same goes for asynchronous programming models. For the Java developer now we have asynch facilities in Servlet 3.0, which work fine in and of themselves, but it's an unanswered question how that percolates up through web frameworks, like Spring or any other. If you've got one asynch enabled servlet, every other piece of servlet componentry in that request pipeline needs to be asynch aware; every filter and so on. Do they have to get in there and re-factor everything? What does that mean for the end developer? For frameworks? How do they and we do things differently?
We also want to keep our eye on how application development should change for the cloud. What we see right now, is PaaS providers doing the right thing in terms of being able to get Java-based workloads, as they currently exist, onto their platforms; so WAR based deployment models, servlet-based applications. But it's really worth asking the question, "Is that the best way to do it with the characteristics of the cloud?"
Chris also talked about looking at re-thinking Spring's error reporting to make it less stack-trace driven for configuration errors and more like the sort of thing you get out of javac, swapping CGLIB proxying out for a more modern alternative and other ease-of-use concerns. Spring Framework will will also moving their version control from Subversion to Git(Hub), and their build system from Ant/Ivy to Gradle as 3.2 development begins.
Spring 3.2 is on a fairly aggressive timeline, targeting Q4 of 2012, broadly to align with the specifications mentioned above.
If anyone from Spring actually want to join JSR107 they would be welcome