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 ProjectDependencies and Technologies Used: - spring-context 5.0.4.RELEASE: Spring Context.
- JDK 1.8
- Maven 3.3.9
|