In this post under Spring Caching, I will show with example how to create custom cache key using annotated method’s target object properties in SpEL.
For our example, we will use the below “Calculator” class as shown below
Calculator
package caching.package8;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Component;@Componentpublic class Calculator { private int start, end; @Cacheable(cacheNames = "addNumbersWithParam_region", key = "#root.target.start * #root.target.end") public int addNumbersWithParam() { System.out.println("Calculating addNumbersWithParam"); int result = 1; for(int i = start; i <= end; i++) { result = result + i; } return result; } //Removed getter and setter for brevity}
In the above class, I have defined two integer properties “start” and “end”, using which I will create the custom cache key.
In the above code, at line 10, I used “@Cacheable” annotation with cache region name “addNumbersWithParam_region” and “key” equal to “#root.target.start * #root.target.end”.
The method which is annotated with “@Cacheable” is named as “addNumbersWithParam”.
In the SpEL code, I have accessed the annotated method’s target object property “start” using “#root.target.start” and “end” using “#root.target.end” to generate custom cache key.
In the expression “target” refers to the object in which the method is defined.
So when we call the method with target object property “start” equal to “5” and “end” equal to “100” and the key will be “500”.
In this way, we can create custom cache key using annotated method’s target object properties in SpEL.
Below is the complete main class for your example.
Main class
package caching.package8;import org.springframework.cache.CacheManager;import org.springframework.cache.annotation.EnableCaching;import org.springframework.cache.concurrent.ConcurrentMapCacheManager;import org.springframework.context.annotation.AnnotationConfigApplicationContext;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;@EnableCaching@Configuration@ComponentScan(basePackages = "caching.package8")public class Example8 { @Bean public CacheManager cacheManager() { return new ConcurrentMapCacheManager(); } public static void main(String[] args) { AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Example8.class); Calculator calculator = annotationConfigApplicationContext.getBean(Calculator.class); calculator.setStart(1); calculator.setEnd(100); System.out.println("First time addNumbersWithParam call started"); System.out.println(calculator.addNumbersWithParam()); System.out.println("First time addNumbersWithParam call finished"); System.out.println("-------------------------------------"); System.out.println("Second time addNumbersWithParam call started"); System.out.println(calculator.addNumbersWithParam()); System.out.println("Second time addNumbersWithParam call finished"); System.out.println("-------------------------------------"); }}
Below is the output
Output
First time addNumbersWithParam call startedCalculating addNumbersWithParam5051First time addNumbersWithParam call finished-------------------------------------Second time addNumbersWithParam call started5051Second time addNumbersWithParam call finished-------------------------------------