Spring Framework 4.1 provides comprehensive support for JCache (JSR-107) annotations using Spring’s existing cache configuration and infrastructure abstraction.
Stephane Nicoll, senior software engineer at Pivotal and committer in Spring Framework talked about the JSR-107 annotations and a series of improvements in Spring Framework 4.1 cache abstraction.
JSR-107 |
Spring |
@CacheResult |
@Cacheable |
@CachePut |
@CachePut |
@CacheRemove |
@CacheEvict |
@CacheRemoveAll |
@CacheEvict(allEntries=true) |
JSR-107 annotations function fairly similar to Spring annotations except for some minor extra functionality like @CacheResult that can cache specific exceptions and force the execution of the method regardless of the content of the cache.
Semantic of @CachePut in JSR-107 is quite different. In JSR-107, @CacheValue annotation is required as an argument to save the value in the cache. JSR-107 has the feature to update the cache before or after the actual method invocation.
@CachePut(cacheName = "books") public void update(ISBN isbn, @CacheValue Book updatedBook) { ... }
Nothing specific needs to be done to enable the JSR-107 support alongside Spring’s declarative annotation support. Both @EnableCaching and the cache:annotation-driven element will automatically enable the JSR-107 support if both the JSR-107 API (javax.cache:cache-api:1.0.0) and the spring-context-support modules are present in the application’s classpath.
Nicoll explained CacheResolver, operation-level customization, class-level customization and JSR-107 integration features which are introduced in Spring 4.1.
CacheResolver is an ability to resolve the cache to use at runtime based on the actual method execution. In earlier Spring releases cache name provided in CacheManager was used as cache which can't be changed at runtime. Nicoll provided the code snippet related to CacheResolver as:
@Cacheable public Book findBook(ISBN isbn) {...}
Operation-level customization is introduced to control cache behavior in a much finer grained manner. Usage of CacheResolver or CacheManager and KeyGenerator are now allowed at the operation level. Following code snippet explains this:
@Cacheable(value="book", keyGenerator="myKeyGenerator") public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
Spring community members and users also want the ability to share operations level customization at method level without enabling any default cache behavior. @CacheConfig annotation is introduced to provide the same customization at class level. Code snippet related to this is as follows:
@CacheConfig(cacheNames="book", keyGenerator="myKeyGenerator") public class BookRepository { @Cacheable public Book findBook(ISBN isbn) {...} public Book thisIsNotCached(String someArg) {...} }
Nicoll mentioned that one of the main goals of the implementation of JSR-107 support was to leverage the functionality of the previous releases of Spring so the existing application transition should be very smooth. He also said cache support actually uses Spring’s caching abstraction internally, which allows reuse of existing caching infrastructure with the standard annotations. He mentioned other small enhancements in Spring 4.1 like better exception handling and a convenient putIfAbsent method on the cache interface.
Sample application to demonstrate the improvements made to the caching abstraction infrastructure and JSR-107 annotations support in Spring is available on GitHub site.
Greg Luck, JSR-107 specification lead, mentioned in his blog, that support for the specification annotations should be provided by an application framework and not by caching providers or vendors.
Caching annotations, though defined in JSR-107, are not meant to be provided by a CachingProvider such as Hazelcast. Instead they must be provided by the dependency injection containers: Spring, Guice, CDI (for Java EE).
Apart from JSR-107 support, Spring 4.1release has the following major new features:
- Annotated JMS listener methods.
- Flexible resolution and transformation of static web resources.
- MVC views: declarative resolution, Groovy markup templates, Jackson's JsonView
- WebSocket refinements: WebSocket scope, SockJS client support, WebSocket stats
- Performance: SpEL compiler mode, concurrency fine-tuning across the container
Juergen Hoeller, Spring Framework project lead, mentioned in Spring 4.1 release post that fundamental system requirements for Spring 4.1 remain the same. System requirements for Spring 4.1 based applications are Java 6+, Servlet 2.5+, JPA 2.0+ as it were in Spring 4.0.