多模塊項目使用枚舉配置spring-cache緩存

一、前言

  1. 近期被刷接口了,考慮增加 本地緩存提高性能,另配置 限流
  2. 使用 spring-cache 注解式緩存,可以提高使用緩存的開發(fā)效率
  3. 不同業(yè)務(wù),可以定制 自己的緩存策略,是基本需求
  4. 多模塊項目,最好在 統(tǒng)一的模塊(如 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;

}

業(yè)務(wù)模塊緩存配置:

@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
@Configuration
public 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";
    }

}

三、總結(jié)

  • 通過 接口 + 枚舉,業(yè)務(wù)模塊不用改common模塊, 新增枚舉 就能 方便的配置、使用緩存,符合 開閉原則
  • 通過 Lombok 的 FieldNameConstants 自動生成 枚舉名稱常量,便于代碼 導(dǎo)航、重構(gòu)
  • 通過 Reflections 庫,common模塊自動加載 各模塊的緩存配置,SimpleCacheManager 組合 各種不同配置的 緩存(CaffeineCacheManager 不能),降低使用成本,提高可維護性
  • sync = true,加鎖,只有一個線程去加載數(shù)據(jù),其他線程阻塞,防止 緩存擊穿
  • alibaba/jetcache:支持TTL和兩級緩存、自動刷新和加載保護 等
  • netease-im/camellia:網(wǎng)易開源,有意思的是 支持基于注解執(zhí)行mget,mevict等批量操作
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容