如何将现有Map缓存改造为Spring @Cacheable实现
如何用Spring Cache替代手动HashMap缓存
看起来你是把Spring Cache的注解用错啦😉,@CacheEvict是用来删除缓存条目的,而你需要的是在插入数据时写入缓存,应该用@CachePut才对。下面一步步教你把手动HashMap缓存替换成Spring Cache,彻底摆脱手动维护缓存的麻烦:
1. 先开启Spring Cache支持
首先要在你的Spring配置类上加上@EnableCaching注解,这是启用Spring Cache功能的前提:
@Configuration @EnableCaching public class CacheConfig { // 可选:自定义缓存管理器,默认会用ConcurrentMapCacheManager,也可以换成Redis等分布式缓存 @Bean public CacheManager cacheManager() { return new ConcurrentMapCacheManager("customer"); } }
2. 改造数据插入逻辑:用@CachePut写入缓存
你原来的代码是手动调用cache.put()把前端ID和数据库生成的ID存入HashMap,现在换成@CachePut注解,它会在方法执行完成后,把返回值自动存入指定缓存:
@Service public class CustomerService { // 删掉原来的手动HashMap,Spring Cache会帮你管理 // private Map<String, Integer> cache = new HashMap<>(); private final DSLContext dsl; // 构造注入Jooq的DSLContext public CustomerService(DSLContext dsl) { this.dsl = dsl; } public void insert(List<Customer> customers) { for (Customer customer : customers) { // 转换Customer为Jooq生成的CustomerRecord CustomerRecord record = dsl.newRecord(CUSTOMER, customer); // 调用带@CachePut的方法,自动写入缓存 saveAndCacheCustomer(record); } } // 单个记录的存储+缓存写入 @CachePut(value = "customer", key = "#record.frontId") public Integer saveAndCacheCustomer(CustomerRecord record) { record.store(); // 执行数据库插入 return record.getId(); // 返回的ID会被存入缓存,key是frontId } }
3. 改造查询逻辑:用@Cacheable自动命中缓存
你的find方法原来只查本地HashMap,现在换成@Cacheable,它会先检查缓存:如果缓存中有对应frontId的条目,直接返回;如果没有,就执行方法体的数据库查询,再把结果存入缓存:
@Cacheable(value = "customer", key = "#frontId") public Integer find(String frontId) { // 这里添加数据库查询逻辑,当缓存未命中时执行 return dsl.select(CUSTOMER.ID) .from(CUSTOMER) .where(CUSTOMER.FRONT_ID.eq(frontId)) .fetchOneInto(Integer.class); }
关键注意事项
- 注解生效的前提:被
@CachePut、@Cacheable标注的方法必须是Spring管理的Bean的方法,而且不能在同一个类内部直接调用(否则Spring AOP无法拦截,注解不生效)。如果必须在类内部调用,可以通过注入自身Bean的方式调用,或者把缓存相关方法抽成单独的Service。 - SpEL表达式正确性:
key="#record.frontId"要确保能正确获取到前端传入的ID,如果你方法参数是Customer对象,就改成key="#customer.frontId",根据实际参数调整。 - 缓存的扩展性:默认的
ConcurrentMapCacheManager是内存缓存,适合单实例应用;如果是分布式应用,直接换成Redis缓存管理器即可,代码逻辑不需要改动。
这样改造后,你就彻底摆脱了手动维护HashMap的麻烦,Spring Cache会自动帮你处理缓存的写入、读取和过期(如果配置的话)。
内容的提问来源于stack exchange,提问作者Adao
相关产品推荐
相关产品推荐

