写点什么

多模块项目使用枚举配置 spring-cache 缓存

作者:javalover123
  • 2023-06-05
    广东
  • 本文字数:1502 字

    阅读完需:约 5 分钟

多模块项目使用枚举配置spring-cache缓存

一、前言

  1. 近期被刷接口了,考虑增加 本地缓存提高性能,另配置 限流

  2. 使用 spring-cache 注解式缓存,可以提高使用缓存的开发效率

  3. 不同业务,可以定制 自己的缓存策略,是基本需求

  4. 多模块项目,最好在 统一的模块(如 common) 加载缓存配置

二、方案

1. 配置缓存:接口 + 枚举 + Lombok

缓存配置接口:


public interface ICacheConfig {
Integer getTtl();
}
复制代码


common 模块缓存配置(使用 Lombok 的 FieldNameConstants 自动生成 常量):


@lombok.Getter@lombok.AllArgsConstructor@lombok.experimental.FieldNameConstants(onlyExplicitlyIncluded = true)public enum CommonCacheConfig implements ICacheConfig {
@FieldNameConstants.Include QUOTE_LEVEL(1000, 2);
private final Integer ttl;
}
复制代码


业务模块缓存配置:


@lombok.Getter@lombok.AllArgsConstructor@lombok.experimental.FieldNameConstants(onlyExplicitlyIncluded = true)public enum QuoteServiceCacheConfig implements ICacheConfig {
@FieldNameConstants.Include HOT_STOCK(1000, 30);
private final Integer ttl;
}
复制代码

2. 多模块配置加载:Reflections + SimpleCacheManager

  • 通过 Reflections 库加载多模块配置

  • SimpleCacheManager 组合 各种不同配置的 缓存


@EnableCaching@Configurationpublic class CacheConfig {    private Logger log = LoggerFactory.getLogger(this.getClass());    @Bean    @Primary    public CacheManager cacheManager() {        final SimpleCacheManager cacheManager = new SimpleCacheManager();
final String prefix = "package";
复制代码


        Set<Class<? extends ICacheConfig>> classes = new Reflections(prefix).getSubTypesOf(ICacheConfig.class);        log.info("cache types|{}|{}", prefix, classes);        List<Cache> caches = classes.stream().flatMap(clazz -> Arrays.stream(clazz.getEnumConstants())).map(config -> {            final Caffeine<Object, Object> cache = Caffeine.newBuilder().recordStats();            Optional.ofNullable(config.getTtl()).ifPresent(t -> cache.expireAfterWrite(t, TimeUnit.SECONDS));            return new CaffeineCache(((Enum) config).name(), cache.build());        }).collect(Collectors.toList());        cacheManager.setCaches(caches);        return cacheManager;    }
复制代码

3. 使用缓存

  • 使用 @Cacheable(cacheNames = CommonCacheConfig.Fields.QUOTE_LEVEL, sync = true) 操作缓存

  • 使用 Lombok 的 FieldNameConstants 自动生成的 常量:


public enum CommonCacheConfig implements ICacheConfig {
public static final class Fields { public static final String QUOTE_LEVEL = "QUOTE_LEVEL"; }
}
复制代码

三、总结

  • 通过 接口 + 枚举,业务模块不用改 common 模块, 新增枚举 就能 方便的配置、使用缓存,符合 开闭原则

  • 通过 Lombok 的 FieldNameConstants 自动生成 枚举名称常量,便于代码 导航、重构

  • 通过 Reflections 库,common 模块自动加载 各模块的缓存配置,SimpleCacheManager 组合 各种不同配置的 缓存(CaffeineCacheManager 不能),降低使用成本,提高可维护性

  • sync = true,加锁,只有一个线程去加载数据,其他线程阻塞,防止 缓存击穿

  • alibaba/jetcache:支持 注解上指定过期时间等配置、两级缓存、自动刷新和加载保护 等

  • netease-im/camellia:网易开源,有意思的是 支持基于注解执行 mget,mevict 等批量操作


本文首先发布于 https://www.890808.xyz/ ,其他平台需要审核更新慢一些。



发布于: 刚刚阅读数: 6
用户头像

javalover123

关注

还未添加个人签名 2016-07-16 加入

还未添加个人简介

评论

发布
暂无评论
多模块项目使用枚举配置spring-cache缓存_Java_javalover123_InfoQ写作社区