Spring缓存自定义KeyGenerator的实现与应用

在Spring框架中,缓存机制是一种常用的优化手段,可以有效减少对数据库等后端系统的访问次数,提高应用性能。而自定义KeyGenerator则是让缓存更加灵活、精准地命中目标数据的关键所在。本文将通过一个实例,详细介绍如何实现并使用自定义的KeyGenerator。
首先,我们需要创建一个自定义的KeyGenerator类。该类需要实现Spring提供的KeyGenerator接口,并重写generate方法。generate方法的参数包括目标对象、方法对象以及方法的参数数组。我们可以通过这些参数来生成一个具有唯一性的缓存键。
java复制
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();
}
}
在上述代码中,我们首先获取目标对象的类名和方法名,然后遍历方法的参数,将参数的类名和值拼接到字符串中,最终生成一个包含类名、方法名和参数信息的字符串作为缓存键。
接下来,我们需要在Spring的配置类中注册自定义的KeyGenerator。这里我们使用Java配置的方式。
java复制
@Configuration
@ComponentScan
@EnableCaching
public class AppConfig {
@Bean
public CacheManager cacheManager() {
List caches = Arrays.asList(new ConcurrentMapCache(“employee-cache”));
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(caches);
return cacheManager;
}
}
在配置类中,我们通过@EnableCaching注解开启缓存支持,并定义了一个CacheManager。CacheManager用于管理缓存,这里我们使用SimpleCacheManager,并创建了一个名为“employee-cache”的缓存。
然后,我们可以在服务类中使用自定义的KeyGenerator。通过在服务类上添加@CacheConfig注解,并设置keyGenerator属性为自定义KeyGenerator的bean名称,就可以在整个服务类中使用自定义的KeyGenerator生成缓存键。
java复制
@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);
}

}
在EmployeeService类中,我们定义了两个方法getEmployeeById和getEmployeeByNameAndDept,这两个方法都使用了@Cacheable注解。当这些方法被调用时,Spring会根据自定义的KeyGenerator生成缓存键,并将方法的返回值缓存起来。如果后续再次调用相同参数的方法,Spring会直接从缓存中获取结果,而不会再次执行方法体内的逻辑。
最后,我们可以通过一个主类来测试整个缓存流程。
java复制
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 map = (Map) cache.getNativeCache();
    map.forEach((key, value) -> {
        System.out.println(key + " = " + value);
    });
}

}
在主类中,我们首先创建了一个AnnotationConfigApplicationContext实例,然后获取EmployeeService的bean。接着,我们分别调用getEmployeeById和getEmployeeByNameAndDept方法,并打印返回的员工对象。最后,我们通过printNativeCache方法打印出缓存中的内容,可以看到缓存键是由自定义的KeyGenerator生成的,包含了类名、方法名和参数信息。
通过这个实例,我们可以看到自定义KeyGenerator在Spring缓存中的强大作用。它可以根据具体的业务需求生成具有唯一性的缓存键,从而让缓存更加精准地命中目标数据,提高应用的性能和效率。在实际项目中,合理地使用自定义KeyGenerator,可以为我们的应用带来显著的性能提升。

你可能感兴趣的:(spring,缓存,java,个人开发)