Close

Spring Cache - Creating Custom KeyGenerator

[Last Updated: Mar 21, 2018]

In this example we will learn how to implement a custom KeyGenerator

To provide a custom key generator, we need to implement the KeyGenerator interface and register the implementation as a bean.

Examples

package com.logicbig.example;

import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;

@Component("myKeyGen")
public class MyCustomKeyGenerator implements KeyGenerator {
    public Object generate(Object target, Method method, Object... params) {
        StringBuilder sb = new StringBuilder();
        sb.append(target.getClass().getSimpleName())
          .append("-")
          .append(method.getName());

        if (params != null) {
            for (Object param : params) {
                sb.append("-")
                  .append(param.getClass().getSimpleName())
                  .append(":").append(param);
            }
        }
        return sb.toString();
    }
}

Java Config

@Configuration
@ComponentScan
@EnableCaching
public class AppConfig {
    @Bean
    public CacheManager cacheManager() {
        List<ConcurrentMapCache> caches = Arrays.asList(new ConcurrentMapCache("employee-cache"));
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        cacheManager.setCaches(caches);
        return cacheManager;
    }
}

A service bean

One way to use our custom KeyGenerator is to assign @CacheConfig#keyGenerator element value as our KeyGenerator bean name:

@Service
@CacheConfig(cacheNames = "employee-cache", keyGenerator = "myKeyGen")
public class EmployeeService {

    @Cacheable
    public Employee getEmployeeById(int id) {
        System.out.println("getEmployeeById() invoked");
        return new Employee(id, "Adam", "IT");
    }

    @Cacheable
    public Employee getEmployeeByNameAndDept(String name, String dept) {
        System.out.println("getEmployeeByNameAndDept() invoked");
        return new Employee(20, name, dept);
    }
}

Instead of @Cacheable#keyGenerator, we can also use @CacheConfig.keyGenerator to define/override custom KeyGenerator.

The main class

public class ExampleMain {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        EmployeeService employeeService = context.getBean(EmployeeService.class);
        System.out.println("-- getting employee by id --");
        Employee employee = employeeService.getEmployeeById(10);
        System.out.println("employee returned: " + employee);

        System.out.println("-- getting employee by name and dept --");
        employee = employeeService.getEmployeeByNameAndDept("Linda", "Admin");
        System.out.println("employee returned: " + employee);

        printNativeCache(context);
    }

    public static void printNativeCache(ApplicationContext context) {
        Cache cache = context.getBean(CacheManager.class).getCache("employee-cache");
        System.out.println("-- native cache --");
        Map<String, Object> map = (Map<String, Object>) cache.getNativeCache();
        map.forEach((key, value) -> {
            System.out.println(key + " = " + value);
        });
    }
}
-- getting employee by id --
getEmployeeById() invoked
employee returned: com.logicbig.example.Employee@1d9b7cce
-- getting employee by name and dept --
getEmployeeByNameAndDept() invoked
employee returned: com.logicbig.example.Employee@4d9e68d0
-- native cache --
EmployeeService-getEmployeeById-Integer:10 = com.logicbig.example.Employee@1d9b7cce
EmployeeService-getEmployeeByNameAndDept-String:Linda-String:Admin = com.logicbig.example.Employee@4d9e68d0

Example Project

Dependencies and Technologies Used:

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

Spring Custom KeyGenerator Example Select All Download
  • spring-custom-cache-key-generator
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • MyCustomKeyGenerator.java

    See Also