Custom Key Generator Spring Cache

Spring Cache is nothing but a store of key-value pairs, where values are the ones returned from @Cacheable methods, whereas, for keys there has to be some strategy to generate them. By default Spring uses a simple key generation based on the following algorithm:

Sep 05, 2019  Just Announced - 'Learn Spring Security OAuth':. Contribute to eugenp/tutorials development by creating an account on GitHub. Just Announced - 'Learn Spring Security OAuth':. Contribute to eugenp/tutorials development by creating an account on GitHub. Cache: Spring cache: custom key generator: May 5, 2018: datetime: BAEL-2292: Oct 22. Just like its sibling, @CacheEvict requires specifying one (or multiple) caches that are affected by the action, allows a custom cache and key resolution or a condition to be specified but in addition, features an extra parameter allEntries which indicates whether a cache-wide eviction needs to be performed rather then just an entry one (based.

このクイックチュートリアルでは、Spring Cacheを使用してカスタムキージェネレータを作成する方法を説明します。 上記のモジュールの紹介については、 この記事へ を参照してください。. Oct 09, 2019 Learn how to implement a custom Spring Cache KeyGenerator. This is responsible for generating every key for each data item in the cache, which would be used to lookup the data item on retrieval. Dec 20, 2016  Sitecore, by default, provides varies options like Vary by Data, Vary by Query String to enable HTML cache (more information about Sitecore caching could be found here). Sometimes none of these options (based on component built type) help the component to get cached by Sitecore cache. In this article I will describe how to introduce. Aug 23, 2018  We are also going to cover the option to create a custom key generator with Spring Cache. Spring Cache API uses a simple KeyGenerator for generating a key to store caching data. The default key generators for Spring Cache SimpleKeyGenerator.This default implementation uses the method parameters to generate the key. Here is the high-level overview for the default key generation. Dec 18, 2014 The Spring Framework provides a simple way to cache the results of method calls with little to no configuration. The examples in this post use Spring 4.1.3 and Spring Data Redis 1.4.1, the latest versions at the time of this writing. Full source code for this post can be found here.

  • If @Cacheable method has no arguments then SimpleKey.EMPTY is used as key.

  • If only one argument is used, then the argument instance is used as key.

  • If more than one argument is used, then an instance of SimpleKey composed of all arguments is used as key.

Note that to avoid key collisions, SimpleKey class overrides hashCode() and equals() methods and compares all parameters of the target method as shown in the following snippets:


Example

In this example, we will understand the default key generation. We will also understand why we may need custom keys in some cases and how to generate them.

Java Config

ConcurrentMapCacheManager is another Spring provided CacheManager implementation that lazily builds ConcurrentMapCache instances for each request.

A service bean

To understand default cache generation (as stated above), we are going to create a no arg, one arg and multiple args @Cacheable methods:

The main class

As seen in above native cache output, the key generation is according the rules we stated in the beginning of this tutorial.

Generating custom keys

What will happen if we create multiple @Cacheable methods having same argument types? Let's see that by creating two no-args methods:

As seen in above output, Spring attempts to retrieved the same cache value of department list (String[]) for the second method. That's because both methods map to the same key value of SimpleKey.EMPTY. To fix this issue we can define a custom key for the second method. @Cacheable method has an element key for that purpose:

@Cacheable#key allows to use Spring Expression Language (SpEL) for computing the key dynamically. Check out this list to understand what expression metadata can be used.

In above example #root.methodName refers to the method which is being invoked.

Let's run ExampleMain2 again: /aes-256-key-generator-java.html.


Also check out this to understand more scenarios where defining custom key generation is desirable.

Example Project

Dependencies and Technologies Used:

  • spring-context 5.0.4.RELEASE: Spring Context.
  • JDK 1.8
  • Maven 3.3.9

Spring 3.1 M1 is out with some very useful features. One of the coolest feature in the latest release is comprehensive Caching support! Spring Framework provides support for transparently adding caching into an existing Spring application. Similar to the transaction support, the caching abstraction allows consistent use of various caching solutions with minimal impact on the code. The cache is applied to Java methods, reducing the number of executions based on the information available. Spring checks if the given method is already executed for given set of parameters. If the method is already executed, Spring uses the cache value and returns it to caller instead of calling the method again. This is a write through cache. This way, expensive methods (whether CPU or IO bound) can be executed only once for a given set of parameters and the result reused without having to actually execute the method again. The caching logic is applied transparently without any interference to the invoker.

Adding Cache support to Spring project

In order to add Cache support to any Spring based project, one needs to declare the configuration using new Spring tag in the schema declaration. Note the cache:annotation-driven tag in above declaration enables the caching in given Spring project.

Using @Cacheable and @CacheEvict annotations

Spring 3.1 M1 provides two very useful Java annotations: @Cacheable and @CacheEvict which allow methods to trigger cache population or cache eviction. Let us take a closer look at each annotation:

@Cacheable annotation

This annotation mark a method cacheable. Thus the result from this method call will be stored into the cache on subsequent invocations with same arguments. In the above code snippet, method profile is marked cacheable using @Cacheable annotation. Also the method is associated with a cache named “persons“. Whenever method profile is called, the Spring framework will check if cached entry is available in persons cache and returns the same without calling profile method. It is also possible to provide multiple cache names if you have multiple caches declared in your application. For example: In above code snippet, we provide two cache names persons and profiles. Spring framework will check in all the caches if entry is available for given method call with argument personId, if at least one cache is hit, then the associated value will be returned.

@CacheEvict annotation

Cache eviction is removing of any unused or stale data from the cache. Opposed to @Cacheable, annotation @CacheEvict demarcates methods that perform cache eviction, that is methods that act as triggers for removing data from the cache. Just like its sibling, @CacheEvict requires one to specify one (or multiple) caches that are affected by the action, allows a key or a condition to be specified but in addition, features an extra parameter

Custom Key Generator Spring Cache Tool

allEntries which indicates whether a cache-wide eviction needs to be performed rather then just an entry one (based on the key): This annotation is very useful when an entire cache region needs to be cleared out. The Spring framework will ignore any key specified in this scenario as it does not apply.

Using Default key

The cache is nothing but a key-value store which stores the data based on certain key. In Spring framework based caching, the method arguments of cached method acts as the source of Key generation. Every key is essentially the Hash-code of these arguments. This approach works well for objects with natural keys as long as the hashCode() reflects that. If that is not the case then for distributed or persistent environments, the strategy needs to be changed as the objects hashCode is not preserved. In fact, depending on the JVM implementation or running conditions, the same hashCode can be reused for different objects, in the same VM instance. To provide a different default key generator, one needs to implement the org.springframework.cache.KeyGenerator interface. Once configured, the generator will be used for each declaration that does not specify its own key generation strategy. By default, all the method arguments are used in Key generation logic. In practice not all methods have only one argument or, worse yet, the parameters are not suitable as cache keys – take for example a variation of the method above: Here we are using just personId in key generation ignoring groupId altogether.

Understand Conditional caching

Spring framework also supports conditional caching letting user to cache certain methods based on some conditions. For example, in following code snippet we cache profiles only for those users who have profileId greater than 50:

Currently supported libraries

There are probably hundreds of cache libraries available which can be used in your JEE project. For now the Spring framework supports following implementations:
  1. JDK ConcurrentMap based Cache
  2. Ehcache based Cache

JDK ConcurrentMap based Cache

The JDK-based Cache implementation resides under org.springframework.cache.concurrent package. It allows one to use

Spring Boot Cache Key

ConcurrentHashMap as a backing Cache store. In above code snippet, we use

Customs Cache Locations

SimpleCacheManager class to create a CacheManager. Note that we have created two caches in our application, one is default and second is persons.

Custom Key Generator Spring Cachet

Ehcache based Cache

The Ehcache implementation is located under org.springframework.cache.ehcache package. Again, to use it, one simply needs to declare the appropriate CacheManager: This setup bootstraps ehcache library inside Spring IoC (through bean ehcache) which is then wired into the dedicated CacheManager implementation. Note the entire ehcache-specific configuration is read from the resource ehcache.xml.

Spring Cache Custom Key Generator

References