Creating custom cache key from method object properties using SpEL

In this post under Spring Caching, I will show with example how to create custom cache key using annotated method’s properties in SpEL.

For our example, we will use the below “Calculator” class as shown below

Calculator

package caching.package7;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
@Component
public class Calculator {
@Cacheable(cacheNames = "addNumbersWithParam_region", key = "#root.method.hashCode() + '_' + (#root.args[0] * #root.args[1])")
public int addNumbersWithParam(int start, int end) {
System.out.println("Calculating addNumbersWithParam");
int result = 1;
for(int i = start; i <= end; i++) {
result = result + i;
}
return result;
}
}

In the above code, at line 8, I used “@Cacheable” annotation with cache region name “addNumbersWithParam_region” and “key” equal to “#root.method.hashCode() + ‘_’ + (#root.args[0] * #root.args[1])”.

The method which is annotated with “@Cacheable” is named as “addNumbersWithParam”

In the SpEL code, I have accessed the annotated method’s hashCode property “#root.method.hashCode()” to generate custom cache key.

So we call the method with argument 5 and 100 and method hashCode is “12345”, the key will be “12345_500”.

In this way, we can create custom cache key using method properties in SpEL.

Below is the complete main class for your example.

Main class

package caching.package7;
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.package7")
public class Example7 {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
}
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Example7.class);
Calculator calculator = annotationConfigApplicationContext.getBean(Calculator.class);
System.out.println("First time addNumbersWithParam(1, 100) call started");
System.out.println(calculator.addNumbersWithParam(1, 100));
System.out.println("First time addNumbersWithParam(1, 100) call finished");
System.out.println("-------------------------------------");
System.out.println("Second time addNumbersWithParam(1, 100) call started");
System.out.println(calculator.addNumbersWithParam(1, 100));
System.out.println("Second time addNumbersWithParam(1, 100) call finished");
System.out.println("-------------------------------------");
}
}

Below is the output

Output

First time addNumbersWithParam(1, 100) call started
Calculating addNumbersWithParam
5051
First time addNumbersWithParam(1, 100) call finished
-------------------------------------
Second time addNumbersWithParam(1, 100) call started
5051
Second time addNumbersWithParam(1, 100) call finished
-------------------------------------

Leave a comment