Creating custom cache key from method name using SpEL

In this post under Spring Caching, I will show with example how to create custom cache key from method name using SpEL.

In SpEL, to access SpEL context object we will use “#root” variable.

This SpEL context object will have below information

  1. reference to target method that is annotated with @Cacheable, @CachePut, or @CacheEvict
  2. reference to target object containing the annotated method
  3. reference to Class object of the target object
  4. annotated target method name
  5. annotated target method arguments
  6. collection of caches used by target method

We can use these information to create our own custom key in SpEL.

Here in this post, I will show how to access method name in SpEL to create our own custom cache key.

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

Calculator

package caching.package6;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
@Component
public class Calculator {
@Cacheable(cacheNames = "addNumbersWithParam_region", key = "#root.methodName + '_' + (#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 have used “@Cacheable” annotation for the method “addNumbersWithParam”.

The cache region name I have given is “addNumbersWithParam_region”

The SpEL that I have used to generate custom key is “#root.methodName + ‘_’ + (#root.args[0] * #root.args[1])” and assigned it to “key” attribute of “@Cacheable” annotation.

I have used the “methodName” property of “#root” object to access the method name.

At runtime if I call the method with arguments “start = 5” and “end = 100”, the key will be “addNumbersWithParam_500”, and the value will be sum of all numbers from 5 to 100.

Next time when I call the method with same arguments, the value is retrieved from the cache using the key “addNumbersWithParam_500” instead of executing the method again.

Below is the main class for your reference.

Main class

package caching.package6;
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.package6")
public class Example6 {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
}
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Example6.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