Skip to content
Stéphane Nicoll edited this page Jan 28, 2014 · 7 revisions

The purpose of this page is to gather the differences between the Spring-based annotations and the JSR 107 caching annotations.

Summary

The table below summarises the annotations that can be used to trigger caching-related operations

Spring JSR 107
@Cacheable @CacheResult
@CachePut @CachePut
@CacheEvict @CacheRemove
@CacheEvict(allEntries = true) @CacheRemoveAll
SPR-11316 @CacheDefaults

Other peripheral concepts that are worth describing:

Spring JSR 107
KeyGenerator (bean lookup) CacheKeyGenerator
CacheManager (bean lookup) CacheResolverFactory

Missing features

@CacheResult

  • If an operation fails and an exception is thrown, the exception can be cached (provided it matches the configured filter). This clearly means that if the operation is invoked with the exact same key, the cached exception will be thrown again (instead of calling the method).
  • Execute the annotated method always (skipGet) with the returned value being cached as normal

@CachePut

  • Specify when the cache should be updated. By default, the cache is updated after the method has completed but afterInvocation allows to customise that
  • Exception handling used only if afterInvocation is true. If the business method throws an exception, the exception type can be filtered to figure out if the cache should be updated or not.

@CacheRemove/@CacheRemoveAll

  • Exception handling used only if afterInvocation is true. If the business method throws an exception the exception type can be filtered to figure out if the cache should be updated or not.

@CacheDefaults

The feature does not exist yet in Spring but SPR-11316 is meant to provide the exact same feature set.

Cache and CacheManager

Ideally, we would support JSR-107 annotations talking to our cache abstraction, which in turn may or may not delegate to a JSR-107 CacheManager. For anything that would need to talk to a JSR-107 compliant CacheManager we can use an adapter.

Semantic differences

Reference to the updated instance used by a put operation

@CachePut actually requires to specify the object to update as a method parameter that is annotated with @CacheValue whereas Spring takes the return value of the method instead.

Cache name mandatory/optional

If no cache name is specified, a default name is generated based on the signature of the method with the JSR. Spring requires a cache name to be set. This may be a problem for users going from the standard annotations to ours and not the other way around. Probably not a concern.

Specifying the key parameters

The JSR uses a @CacheKey to specify the parameters to include in the key. If none is set, all parameters are taken into account or a CacheKeyGenerator class can be specified.

Spring uses either SPeL or the name of a KeyGenerator bean.

An adapter for the CacheKeyGenerator could be specified quite easily and we could detect the @CacheKey annotations to generate the proper key.

Annotations inheritance

The Spring annotations are inherited while the JSR ones are not. This will probably lead to some confusions for users switching from our annotations to the standard ones.

beforeInvocation vs. afterInvocation

@CacheEvict specifies a beforeInvocation that defaults to false (that is the eviction is always performed after the business method has completed). @CacheRemove (and @CacheRemoveAll) specifies a afterInvocation that defaults to true. There's no real difference in semantics here as the defaulting applies consistently but the naming difference is worth noticing.