121 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| [[cache-jsr-107]]
 | |
| = JCache (JSR-107) Annotations
 | |
| 
 | |
| Since version 4.1, Spring's caching abstraction fully supports the JCache standard
 | |
| (JSR-107) annotations: `@CacheResult`, `@CachePut`, `@CacheRemove`, and `@CacheRemoveAll`
 | |
| as well as the `@CacheDefaults`, `@CacheKey`, and `@CacheValue` companions.
 | |
| You can use these annotations even without migrating your cache store to JSR-107.
 | |
| The internal implementation uses Spring's caching abstraction and provides default
 | |
| `CacheResolver` and `KeyGenerator` implementations that are compliant with the
 | |
| specification. In other words, if you are already using Spring's caching abstraction,
 | |
| you can switch to these standard annotations without changing your cache storage
 | |
| (or configuration, for that matter).
 | |
| 
 | |
| 
 | |
| [[cache-jsr-107-summary]]
 | |
| == Feature Summary
 | |
| 
 | |
| For those who are familiar with Spring's caching annotations, the following table
 | |
| describes the main differences between the Spring annotations and their JSR-107
 | |
| counterparts:
 | |
| 
 | |
| .Spring vs. JSR-107 caching annotations
 | |
| [cols="1,1,3"]
 | |
| |===
 | |
| | Spring | JSR-107 | Remark
 | |
| 
 | |
| | `@Cacheable`
 | |
| | `@CacheResult`
 | |
| | Fairly similar. `@CacheResult` can cache specific exceptions and force the
 | |
|   execution of the method regardless of the content of the cache.
 | |
| 
 | |
| | `@CachePut`
 | |
| | `@CachePut`
 | |
| | While Spring updates the cache with the result of the method invocation, JCache
 | |
|   requires that it be passed it as an argument that is annotated with `@CacheValue`.
 | |
|   Due to this difference, JCache allows updating the cache before or after the
 | |
|   actual method invocation.
 | |
| 
 | |
| | `@CacheEvict`
 | |
| | `@CacheRemove`
 | |
| | Fairly similar. `@CacheRemove` supports conditional eviction when the
 | |
|   method invocation results in an exception.
 | |
| 
 | |
| | `@CacheEvict(allEntries=true)`
 | |
| | `@CacheRemoveAll`
 | |
| | See `@CacheRemove`.
 | |
| 
 | |
| | `@CacheConfig`
 | |
| | `@CacheDefaults`
 | |
| | Lets you configure the same concepts, in a similar fashion.
 | |
| |===
 | |
| 
 | |
| JCache has the notion of `javax.cache.annotation.CacheResolver`, which is identical
 | |
| to the Spring's `CacheResolver` interface, except that JCache supports only a single
 | |
| cache. By default, a simple implementation retrieves the cache to use based on the
 | |
| name declared on the annotation. It should be noted that, if no cache name is
 | |
| specified on the annotation, a default is automatically generated. See the javadoc
 | |
| of `@CacheResult#cacheName()` for more information.
 | |
| 
 | |
| `CacheResolver` instances are retrieved by a `CacheResolverFactory`. It is possible
 | |
| to customize the factory for each cache operation, as the following example shows:
 | |
| 
 | |
| [source,java,indent=0,subs="verbatim,quotes"]
 | |
| ----
 | |
| 	@CacheResult(cacheNames="books", cacheResolverFactory=MyCacheResolverFactory.class) <1>
 | |
| 	public Book findBook(ISBN isbn)
 | |
| ----
 | |
| <1> Customizing the factory for this operation.
 | |
| 
 | |
| NOTE: For all referenced classes, Spring tries to locate a bean with the given type.
 | |
| If more than one match exists, a new instance is created and can use the regular
 | |
| bean lifecycle callbacks, such as dependency injection.
 | |
| 
 | |
| Keys are generated by a `javax.cache.annotation.CacheKeyGenerator` that serves the
 | |
| same purpose as Spring's `KeyGenerator`. By default, all method arguments are taken
 | |
| into account, unless at least one parameter is annotated with `@CacheKey`. This is
 | |
| similar to Spring's xref:integration/cache/annotations.adoc#cache-annotations-cacheable-key[custom key generation declaration]
 | |
| . For instance, the following are identical operations, one using
 | |
| Spring's abstraction and the other using JCache:
 | |
| 
 | |
| [source,java,indent=0,subs="verbatim,quotes"]
 | |
| ----
 | |
| 	@Cacheable(cacheNames="books", key="#isbn")
 | |
| 	public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
 | |
| 
 | |
| 	@CacheResult(cacheName="books")
 | |
| 	public Book findBook(@CacheKey ISBN isbn, boolean checkWarehouse, boolean includeUsed)
 | |
| ----
 | |
| 
 | |
| You can also specify the `CacheKeyResolver` on the operation, similar to how you can
 | |
| specify the `CacheResolverFactory`.
 | |
| 
 | |
| JCache can manage exceptions thrown by annotated methods. This can prevent an update of
 | |
| the cache, but it can also cache the exception as an indicator of the failure instead of
 | |
| calling the method again. Assume that `InvalidIsbnNotFoundException` is thrown if the
 | |
| structure of the ISBN is invalid. This is a permanent failure (no book could ever be
 | |
| retrieved with such a parameter). The following caches the exception so that further
 | |
| calls with the same, invalid, ISBN throw the cached exception directly instead of
 | |
| invoking the method again:
 | |
| 
 | |
| [source,java,indent=0,subs="verbatim,quotes"]
 | |
| ----
 | |
| 	@CacheResult(cacheName="books", exceptionCacheName="failures"
 | |
| 				cachedExceptions = InvalidIsbnNotFoundException.class)
 | |
| 	public Book findBook(ISBN isbn)
 | |
| ----
 | |
| 
 | |
| 
 | |
| [[enabling-jsr-107-support]]
 | |
| == Enabling JSR-107 Support
 | |
| 
 | |
| You do not need to do anything specific to enable the JSR-107 support alongside Spring's
 | |
| declarative annotation support. Both `@EnableCaching` and the `cache:annotation-driven`
 | |
| XML element automatically enable the JCache support if both the JSR-107 API and the
 | |
| `spring-context-support` module are present in the classpath.
 | |
| 
 | |
| NOTE: Depending on your use case, the choice is basically yours. You can even mix and
 | |
| match services by using the JSR-107 API on some and using Spring's own annotations on
 | |
| others. However, if these services impact the same caches, you should use a consistent
 | |
| and identical key generation implementation.
 |