[020][缓存模块]基于 BeanCreator 的缓存管理器创建器模式设计与实践

简介: 本文介绍基于`BeanCreator`函数式接口的缓存管理器创建器模式,统一抽象创建逻辑、单例缓存与类型信息。支持Caffeine、Redis、多级缓存及租户隔离,采用双重检查锁保障线程安全,兼顾配置驱动、可组合性与测试友好性,提升Spring应用缓存架构的可维护性与扩展性。(239字)

[020][缓存模块]基于 BeanCreator 的缓存管理器创建器模式设计与实践

本项目代码:https://gitee.com/yunjiao-source/tutorials4j/tree/master/framework

1. 引言

在复杂的 Spring 应用架构中,缓存管理器的创建与管理是一项常见且关键的任务。不同场景可能需要不同的缓存实现(Caffeine、Redis、多级缓存),甚至需要支持租户隔离等高级特性。传统的做法是在配置类中直接 new 出缓存管理器实例,并手动处理单例缓存。这种方式会导致配置代码臃肿、单例逻辑重复、难以测试等问题。

为了解决这些问题,我们设计了一套基于 BeanCreator 函数式接口的创建器体系。该体系将缓存管理器的创建逻辑单例缓存类型信息进行抽象,形成了可复用、可组合、可扩展的创建器组件。本文将从 BeanCreator 接口设计出发,逐步分析其在缓存管理器创建场景下的具体实现与应用,并展示如何通过这一模式优雅地支持 Caffeine、Redis、多级缓存以及租户隔离。


2. BeanCreator——统一的 Bean 创建契约

BeanCreator 是一个函数式接口,定义了三种核心操作:

@FunctionalInterface
public interface BeanCreator<T> {
   
    T getInstance();               // 获取单例实例(优先从缓存获取)
    default T newInstance() {
         // 直接创建新实例,不走缓存
        throw new UnsupportedOperationException();
    }
    default Class<T> getBeanClass() {
    // 返回 Bean 的实际类型
        throw new UnsupportedOperationException();
    }
}
  • getInstance():使用者获取实例的唯一入口。实现者通常在此方法中实现单例缓存逻辑(如双重检查锁定),保证整个应用上下文只有一个目标实例。
  • newInstance():绕过缓存直接创建新实例,用于需要全新实例的场合(如单元测试或强制重建)。默认抛出异常,由子类按需重写。
  • getBeanClass():返回创建的 Bean 的精确 Class 类型,便于框架进行类型识别或元数据处理。

该接口的设计遵循了模板方法模式工厂模式的混合思想:上层调用者无需关心实例如何创建、是否单例,只需调用 getInstance();具体创建细节交由子类实现。

3. 缓存管理器创建器体系

针对 Spring 的 CacheManager 抽象,我们定义了子接口 CacheManagerCreator<T extends CacheManager>,它仅仅是 BeanCreator<T> 的标记性继承,表示所有缓存管理器的创建器都应遵循这一套行为规范。

随后,我们为每种缓存实现编写了对应的创建器:

创建器类 管理的缓存管理器类型 特点
CaffeineCacheManagerCreator CaffeineCacheManager 基于 Caffeine 的本地缓存,支持 YAML 配置
RedisCacheManagerCreator RedisCacheManager 基于 Redis 的分布式缓存,支持自定义器链
MultiLevelCacheManagerCreator MultiLevelCacheManager 组合 Caffeine(L1)和 Redis(L2)的多级缓存
TenantCaffeineCacheManagerCreator TenantCaffeineCacheManager 租户隔离的 Caffeine 缓存(装饰器模式)
TenantMultiLevelCacheManagerCreator MultiLevelCacheManager 租户隔离的多级缓存

这些创建器都采用了双重检查锁定(Double-Checked Locking) 实现线程安全的单例模式,例如 CaffeineCacheManagerCreator 中的核心逻辑:

public CaffeineCacheManager getInstance() {
   
    if (instance != null) return instance;
    synchronized (this) {
   
        if (instance != null) return instance;
        instance = newInstance();
    }
    return instance;
}

这种写法既保证了第一次访问后的高性能(无锁读取),又确保了多线程环境下的唯一性。同时,每个创建器都正确实现了 newInstance()getBeanClass() 方法,为框架或上层模块提供了完整的实例化能力。

4. 各创建器实现亮点分析

4.1 CaffeineCacheManagerCreator

  • 依赖注入:通过构造函数接收 CacheCaffeineProperties 配置对象和 Caffeine<Object, Object> 构造器实例。
  • 灵活扩展:内部使用了 FlexibleCaffeineCacheManager(非标准 Spring 类,但可以看出对配置的精细控制),允许针对不同缓存名称设置差异化过期策略(见 YAML 中的 named-caches)。
  • 类型暴露getBeanClass() 返回 CaffeineCacheManager.class,符合面向接口编程的原则。

4.2 RedisCacheManagerCreator

  • 复杂初始化:需要 RedisConnectionFactory、配置属性、两个自定义器列表(RedisCacheManagerBuilderCustomizerCacheManagerCustomizer<RedisCacheManager>)。
  • 配置填充:通过 RedisUtils.fillConfiguration() 根据 properties 设置默认的序列化、TTL、空值缓存等。
  • 自定义器链:先对 RedisCacheManagerBuilder 应用 builder 级 customizer,再对构建完成的 RedisCacheManager 应用 manager 级 customizer,提供了极高的定制自由度。

4.3 MultiLevelCacheManagerCreator

  • 组合模式:它不自己创建底层的 Caffeine 和 Redis 管理器,而是依赖传入的两个创建器:
    return new MultiLevelCacheManager(
        caffeineCacheManagerCreator.getInstance(),
        redisCacheManagerCreator.getInstance()
    );
    
  • 无状态:自身只负责组合,真正的缓存管理器创建和单例维护委托给内部创建器。这体现了单一职责原则组合优于继承

4.4 租户感知创建器

TenantCaffeineCacheManagerCreatorTenantMultiLevelCacheManagerCreator 展示了如何在不修改原有创建器代码的前提下实现租户隔离:

  • TenantCaffeineCacheManager 装饰了普通的 CaffeineCacheManager,在缓存操作时自动注入租户标识。
  • 租户创建器直接复用原有的 CaffeineCacheManagerCreator 实例,仅通过装饰器包装返回。
  • TenantMultiLevelCacheManagerCreator 更是组合了租户级 Caffeine 创建器和普通 Redis 创建器,实现了一级缓存租户隔离,二级缓存共享的混合策略。

这种设计使得租户能力的引入变得非侵入,符合开闭原则。

5. 在 Spring 配置中的落地

示例文件 CacheableConfig 展示了如何在 Spring 应用中使用这些创建器:

@EnableCaching
@Configuration
@Profile("cacheable")
public class CacheableConfig implements CachingConfigurer {
   
    @Autowired private RedisCacheManagerCreator redisCacheManagerCreator;

    @Bean
    CaffeineCacheManager caffeineCacheManager(CaffeineCacheManagerCreator creator) {
   
        return creator.getInstance();   // 通过创建器获取单例
    }

    @Bean
    @Override
    public CacheManager cacheManager() {
   
        return redisCacheManagerCreator.getInstance(); // 设为默认 CacheManager
    }
}
  • Profile 激活@Profile("cacheable") 使得该配置仅在特定环境生效。
  • 显式 Bean 注册:虽然 CaffeineCacheManagerCreator 本身可能已被 Spring 管理,但配置类仍然通过 @Beancreator.getInstance() 的结果注册为 Spring Bean,这样做的好处是:
    • 让 Spring 容器也能感知到该缓存管理器(例如用于 @CacheablecacheManager 属性引用)。
    • 保持与标准 Spring Boot 自动配置的兼容性。
  • 实现 CachingConfigurer:重写 cacheManager() 方法可以全局指定默认的 CacheManager,这里使用了 Redis 缓存管理器作为默认实现。

而在服务层,CaffeineCacheableService 通过 @CacheConfig(cacheManager = "caffeineCacheManager") 显式指定使用 Caffeine 缓存,而 RedisCacheableService 没有指定,因此会使用默认的 Redis 管理器。这种灵活性正是得益于创建器模式——我们可以轻松地在不同 Service 中切换不同的缓存实现,而无需修改业务逻辑。

6. 配置驱动的缓存策略

application-cacheable.yml 展示了如何通过外部配置精细化控制每种缓存管理器的行为:

tutorials4j:
  cache:
    caffeine:
      expire-after-write: 2m        # 全局默认
      named-caches:
        users:
          expire-after-write: 5s     # 针对 users 缓存单独配置
    redis:
      timeToLive: 2m
      keyPrefix: share
      named-caches:
        users:
          timeToLive: 10s
          keyPrefix: user
        orders:
          timeToLive: 20s
          cacheNullValues: true

这些配置会被 CacheCaffeinePropertiesCacheRedisProperties 加载,并最终由各创建器在 newInstance() 时使用。CaffeineCacheManagerCreator 通过 FlexibleCaffeineCacheManager 支持每个缓存名称独立配置过期时间;RedisCacheManagerCreator 则通过 RedisCacheConfiguration 的个性化能力实现了类似效果。这种声明式配置 + 创建器封装的模式,极大地减少了样板代码。

7. 总结

BeanCreator 及其在缓存管理器场景下的实现,提供了一种优雅、可扩展的创建器模式。它具有以下优点:

  • 职责清晰:创建逻辑、单例控制、类型信息三者分离。
  • 线程安全:所有创建器都使用成熟的双重检查锁定模式,无需调用方额外同步。
  • 可组合性:多级缓存创建器直接依赖子创建器,租户创建器通过装饰增强,无需修改原有类。
  • 配置友好:与 Spring 的 @ConfigurationProperties 无缝集成,支持细粒度缓存策略。
  • 测试友好:可通过 Mock 创建器或直接调用 newInstance() 进行单元测试。

该模式不仅适用于缓存管理器,也可以推广到任何需要复杂创建逻辑且需要单例保证的组件(如数据源、连接池、消息生产者等)。通过抽象出 BeanCreator 接口,我们为整个框架的组件创建提供了统一的语义,降低了系统复杂度,提高了代码的可维护性和可测试性。

在实际项目中,建议将这种创建器模式与 Spring 的依赖注入容器结合使用:让创建器本身成为 Spring Bean,并在需要实例的地方注入创建器并调用 getInstance()。这样做既利用了 Spring 的生命周期管理,又保留了手工控制单例的灵活性,是一种值得推广的实践。

目录
相关文章
|
19天前
|
存储 人工智能 弹性计算
阿里云产品与AI产品组合购活动更新:最新套餐配置与组合购价格参考
阿里云产品组合购活动更新,涵盖AI产品与云产品两大板块,覆盖90%+上云场景。AI产品组合购包含Open Claw经典套餐(78元起)、AI Agent搭建全套餐(112元起)、PAI ArtLab生图套餐(112.98元起)等,支持从个人助理到企业级Agent的快速部署。云产品组合购包含经典"99"计划、0代码建站套餐(域名低至1元)、安全加速全家桶、视频直播全链路服务等,适合个人开发者及企业用户按需选购。
|
29天前
|
运维 Java 开发者
[015][web模块]基于Spring Boot的HTTP客户端日志与默认配置实战
本文详解基于Spring Boot的HTTP客户端统一配置方案,支持RestTemplate、RestClient与WebClient三种客户端,实现无侵入的日志记录(请求/响应头、状态码)、默认请求头注入(如X-Request-Id)、非2xx异常自动转换及链路追踪支持,全部通过Customizer与Filter机制自动装配,开箱即用,提升微服务调用可观测性与开发效率。(239字)
179 5
[015][web模块]基于Spring Boot的HTTP客户端日志与默认配置实战
|
19天前
|
弹性计算 人工智能
使用阿里云官方扩展程序安装Hermes到ECS(不写代码,分钟级一键安装)
Hermes Agent是Nous Research开源的自我进化AI智能体。本文详解如何通过阿里云OOS扩展程序,3~5分钟一键安装至ECS,全程免手动配置,并指导大模型凭证配置与快速验证。
|
19天前
|
SQL 自然语言处理 数据可视化
2026年企业如何应用BI系统?从数据集成到智能决策的实战指南
2026年,企业亟需突破数据孤岛与决策滞后困局。本文以瓴羊Quick BI为实践载体,提供“集成→建模→分析→决策”四步落地指南:支持30+数据源直连、业务语义化建模、自然语言查询与AI归因、预警触发审批/调价等自动行动。附零售库存优化等真实案例及高频FAQ,助力企业让数据真正“开口说话”、驱动业务。(239字)
|
19天前
|
API 数据库
邮箱验证-邮箱校验-邮件地址验证-电子邮件地址校验接口介绍
本API提供邮箱验证服务,可快速检测邮箱格式、MX记录、是否为一次性邮箱等,有效提升邮件送达率、保护发件人信誉、降低营销成本、维护客户数据库准确性,助力企业高效精准触达真实用户。
101 1
|
19天前
|
人工智能 API 网络安全
OpenClaw新手必看!阿里云一键部署+百炼Token Plan开通与配置完整手册
2026年,AI智能体(Agent)已成为个人与团队提升效率的核心工具,OpenClaw(原Clawdbot)凭借轻量化、全场景适配、可深度自定义的优势,成为最受欢迎的开源AI智能体框架之一。它能对接阿里云百炼大模型,实现代码生成、任务自动化、信息检索、多平台交互等能力,无需复杂开发即可拥有专属AI助手。
159 2
|
1月前
|
缓存 NoSQL 算法
【Redis】Redis——过期键删除策略、内存淘汰8种策略、LRU/LFU实现
Redis过期删除与内存淘汰是两大核心内存管理机制:前者按TTL自动清理失效键(惰性+定期组合),后者在`maxmemory`超限时主动淘汰键(8种策略,含LRU/LFU近似实现)。二者目标、触发条件与作用范围截然不同,需精准区分与配置。
|
1月前
|
缓存 安全 搜索推荐
[004][缓存模块]Caffeine缓存自定义:构建灵活的Spring Boot缓存管理器
本文介绍Spring Boot中Caffeine缓存的灵活定制方案:通过自定义`FlexibleCaffeineCacheManager`,支持按缓存名(如users/products)独立配置过期策略、容量等参数,兼顾全局默认与个性化需求;结合线程安全创建器、属性合并机制及无缝Spring集成,实现高性能、易扩展、零侵入的本地缓存管理。(239字)
118 2
|
1月前
|
缓存 NoSQL Java
[006][缓存模块] 两级缓存实战:基于 Caffeine + Redis 的多级缓存设计与实现
本文介绍基于Caffeine(本地)+ Redis(分布式)的两级缓存实战方案,通过自定义`MultiLevelCache`与`MultiLevelCacheManager`,实现Spring Cache标准接口下的透明多级缓存:读优先本地(纳秒级)、未命中查Redis并回填;写同步更新两级,兼顾高性能与数据共享。代码开源可直接集成。
182 0
|
19天前
|
缓存 运维 监控
KKCE网站测速:深度检测站点性能,精细化运维优化方案
网站性能直接影响用户体验与运营效果。本文详解专业测速(如KKCE)的必要性:破除本地测试误区,通过多节点、多场景检测,精准识别加载延迟、首屏慢、跨域卡顿等隐性问题;涵盖服务器响应、首屏时间、资源加载等核心指标;强调标准化测试与常态化巡检,助力高效优化——压缩资源、配置缓存、优化链路、维护服务器,实现性能持续提升。(239字)
103 0