Spring Cache Custom Key Generator
From the spring documentation :
Jun 29, 2017 Spring Boot cache with. Spring.cache.type=redis spring.redis.host=192. @CacheConfig — Class level annotation allows to specify global values for annotations like cache name or key generator. 2017 October 1. The default key generators for Spring Cache SimpleKeyGenerator and SimpleKey only consider the argument types of a method and not the method itself. This means that if you have two different methods with the same argument types (eg.
How can I specify @Cachable
to use isbn
and checkWarehouse
as key?
Dec 18, 2014 The solution is to implement a custom key generator that will generate the key for each method to be unique by default. Adding a keyGenerator bean to your CacheConfig class (shown above) will give you this functionality. Note that for your custom key generator to work by default, this class must implement the CachingConfigurer interface. Spring Cache - Creating Custom KeyGenerator; Spring Cache Evict; Spring Cache Key Generation; Understating Spring Cache abstraction with basic example; Using WebSockets in Spring MVC application; Using @JmsListener to listen JMS messages; Using a MessageListener to receive messages and JmsTemplate to send messages; Sending and Receiving messages with JmsTemplate. 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 algorithm. SimpleKeyGenerator is the default generator provided by Spring. Spring automatically configures this as the KeyGenerator if one has not been configured. It uses the method parameters provided to generate the key. If you have two methods that use the same cache name and the same set of parameter types. Functional Interface: This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference. @FunctionalInterface public interface KeyGenerator Cache key generator. Used for creating a key based on the given method (used as context) and its parameters.
Update: Current Spring cache implementation uses all method parameters as the cache key if not specified otherwise. If you want to use selected keys, refer to Arjan’s answer which uses SpEL list {#isbn, #includeUsed}
which is the simplest way to create unique keys.
From Spring Documentation
On some systems such as lubuntu where the password and keys (seahorse) app is not available, a good and simple way to make PGP key is using gpa (GNU privacy assistant). It is a graphical frontend for gpg. Generate pgp key linux. Creating your OpenPGP keys with gpgStep 1: Open a terminal and type: gpg -gen-keyStep 2: GPG will now ask you a number of questions about the type of key you want to generate. This method also apply to others ubuntu derivatives. install gpasudo apt install gpg gpa2.launch gpa from your applications menu3.Hit the Keys menu then select New Key.
The default key generation strategy changed with the release of Spring
4.0. Earlier versions of Spring used a key generation strategy that, for multiple key parameters, only considered the hashCode() of
parameters and not equals(); this could cause unexpected key
collisions (see SPR-10237 for background). The new
‘SimpleKeyGenerator’ uses a compound key for such scenarios.
Self signed keystore can be easily created with keytool command. Generate jwt private key from pkcs file online. Openssl pkcs12 -export -in path to certificate -inkey path to private key -certfile path to certificate -out testkeystore.p12If your private key has a password, It would promote to enter the password of private key. But if you have a private key and a CA signed certificate of it, You can not create a key store with just one keytool command.You need to go through following to get it done.Step 1. You can use openssl command for this. Create PKCS 12 file using your private key and CA signed certificate of it.
Before Spring 4.0
I suggest you to concat the values of the parameters in Spel expression with something like key='#checkWarehouse.toString() + #isbn.toString()')
, I believe this should work as org.springframework.cache.interceptor.ExpressionEvaluator returns Object, which is later used as the key so you don’t have to provide an int
in your SPEL expression.
As for the hash code with a high collision probability – you can’t use it as the key.
Someone in this thread has suggested to use T(java.util.Objects).hash(#p0,#p1, #p2)
but it WILL NOT WORK and this approach is easy to break, for example I’ve used the data from SPR-9377 :
Both lines print -636517714 on my environment.
P.S. Actually in the reference documentation we have
I think that this example is WRONG and misleading and should be removed from the documentation, as the keys should be unique.
P.P.S. also see https://jira.springsource.org/browse/SPR-9036 for some interesting ideas regarding the default key generation.
I’d like to add for the sake of correctness and as an entertaining fact that using a secure cryptographic hash function like SHA256, due to the properties of such function IS possible for this task, but to compute it every time may be too expensive.
After some limited testing with Spring 3.2, it seems one can use a SpEL list: {.., .., ..}
. This can also include null
values. Spring passes the list as the key to the actual cache implementation. When using Ehcache, such will at some point invoke List#hashCode(), which takes all its items into account. (I am not sure if Ehcache only relies on the hash code.)
I use this for a shared cache, in which I include the method name in the key as well, which the Spring default key generator does not include. This way I can easily wipe the (single) cache, without (too much…) risking matching keys for different methods. Like:
Of course, if many methods need this and you’re always using all parameters for your key, then one can also define a custom key generator that includes the class and method name:
…with:
You can use a Spring-EL expression, for eg on JDK 1.7:
Customkey Generator
This will work
@Cacheable(value=”bookCache”, key=”#checkwarehouse.toString().append(#isbn.toString())”)