V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
trifolium2wang
V2EX  ›  推广

发现一个好用的 spring 项目缓存注解

  •  
  •   trifolium2wang · 2024-02-26 09:28:55 +08:00 · 1903 次点击
    这是一个创建于 372 天前的主题,其中的信息可能已经有所发展或是发生改变。

    tutu-cache 是为了解决 SpringCache 缓存注解不够灵活的问题而做的 SpringAop 项目。使用 tutu-cache 注解来代替 @Cacheable 和 @CacheEvict 等注解

    开源地址: https://github.com/trifolium-x/tutu-cache

    文档地址:tutu-cache doc

    快速开始

    1. 在 springBoot 中的使用

      • 引入 jar 依赖包

        
        <dependencies>
        
          <dependency>
        
              <groupId>co.tunan.tucache</groupId>
        
              <artifactId>tucache-spring-boot-starter</artifactId>
        
              <version>1.0.4.RELEASE</version>
        
          </dependency>
        
          <!-- 建议使用 redis 或者直接忽略使用本地缓存 -->
        
          <dependency>
        
              <groupId>org.springframework.boot</groupId>
        
              <artifactId>spring-boot-starter-data-redis</artifactId>
        
          </dependency>
        
        </dependencies>
        
          <!-- 或者其他缓存 -->
        
        

    使用 tu-cache

    1. 使用 tu-cache 对 service 中的方法返回的数据进行缓存

      
      @TuCache("test_service:getList")
      
      public List<String> getList(){
      
          return Arrays.asList("tu","nan");
      
      }
      
      
    2. 使用 tu-cache 删除缓存中的数据

      
      @TuCacheClear("test_service:getList")
      
      public void delList(){
      
      }
      
      
    3. @TuCache 参数

      • String key() default "" 缓存的字符串格式 key,支持 spEl 表达式(使用#{}包裹 spEl 表达式),默认值为方法签名

      • long expire() default -1 缓存的过期时间,单位(秒),默认永不过期. (在 1.0.4.RELEASE 以上版本中建议使用 timeout)

      • boolean resetExpire() default false 每次获取数据是否重置过期时间.

      • TimeUnit timeUnit() default TimeUnit.SECONDS 缓存的时间单位.

      • String condition() default "true" 扩展的条件过滤,值为 spEl 表达式(直接编写表达式不需要使用#{}方式声明为 spEl)

      • 样例:

        
        @TuCache(key="test_service:getList:#{#endStr}", timeout = 10, timeUnit=TimeUnit.SECONDS)
        
        public List<String> getList(String endStr){
        
            return Arrays.asList("tu","nan",endStr);
        
        }
        
        // 如果需要当前对象的的方法
        
        @TuCache(key="test_service:getList:#{#this.endStr()}", timeout = 120)
        
        public List<String> getList(){
        
            return Arrays.asList("tu","nan",endStr());
        
        }
        
        // 使用 springBean, (使用安全访问符号?.,可以规避 null 错误,具体用法请查看 spEl 表达式)
        
        @TuCache(key="test_service:getList:#{@springBean.endStr()}", timeout = 120)
        
        public List<String> springBeanGetList(){
        
            return Arrays.asList("tu","nan",springBean.endStr());
        
        }
        
        // 使用 condition,当 name 的长度>=5 时进行缓存
        
        @TuCache(key="test_service:getList:#{#name}", condition="#name.length() >= 5")
        
        public List<String> springBeanGetList(String name){
        
            return Arrays.asList("tu","nan",name);
        
        }
        
        public String endStr(){
        
          return "end";
        
        }
        
        
    4. @TuCacheClear 参数

      • String[] key() default {} 删除的 key 数组,支持 spEl 表达式(使用#{}包裹 spEl 表达式)

      • String[] keys() default {} 模糊删除的缓存 key 数组,支持 spEl 表达式(使用#{}包裹 spEl 表达式),对应 redis 中deleteKeys("test_service:")

      • boolean async() default false 是否异步删除,无需等待删除的结果

      • String condition() default "true" 扩展的条件过滤,值为 spEl 表达式(直接编写表达式不需要使用#{}方式声明为 spEl)

      • 样例:

        
        @TuCacheClear(key={"test_service:itemDetail:#{#id}"})
        
        public void deleteItem(Long id){
        
        }
        
        // 如果需要调用本地的方法
        
        @TuCacheClear(keys={"test_service:itemList:","test_service:itemDetail:#{#id}"}, async = true)
        
        public void deleteItem(Long id){
        
        }
        
        
      • 注意 key 和 keys 的区别

    5. condition 的用法

      • condition 要求 spEL 返回一个 boolean 类型的值,例如:

        • condition = "#param.startsWith('a')"

        • condition = "false"

    个性化设置

    • tutu-cache 默认提供了 RedisTuCacheService,如果用户使用的缓存是 redis 并配置了 redisTemplate 的 bean 则自动使用该默认缓存服务。

    • 用户使用其他缓存,则需要自定义 TuCacheService ,实现该接口并注入到 TuCacheBean 中

    • 在 SpringBoot 中在 Configure 类中配置相应的 bean 自动使用自定义的 bean

    • 如果用户需要每个缓存前面添加同意的 keyPrefix ,TuCacheBean 的 prefixKey 参数

    • springBoot 中配置

      
      tucache:
      
        enabled: true
      
        cache-type: redis
      
        profiles:
      
          cache-prefix: "my_tu_key_test:"
      
          # ...
      
      
    14 条回复    2024-02-26 10:24:11 +08:00
    monkeyWie
        1
    monkeyWie  
       2024-02-26 09:35:57 +08:00
    没看出来解决了什么痛点
    diagnostics
        2
    diagnostics  
       2024-02-26 09:52:23 +08:00   ❤️ 3
    哥们,你是失忆了吗?这不是你自己写的项目吗?
    diagnostics
        3
    diagnostics  
       2024-02-26 09:54:13 +08:00
    没想到 2024 了,还能看到 spring boot 里面使用 xml 配置 bean
    Martens
        4
    Martens  
       2024-02-26 09:54:17 +08:00
    推广
    28Sv0ngQfIE7Yloe
        5
    28Sv0ngQfIE7Yloe  
       2024-02-26 09:56:34 +08:00
    >>> tutu-cache 是为了解决 SpringCache 缓存注解不够灵活的问题而做的 SpringAop 项目

    举个例子呗,在那些场景下使用你这个框架更适合啊?
    Qlccks2
        6
    Qlccks2  
       2024-02-26 09:58:25 +08:00   ❤️ 1
    推广就推广,少一点套路。
    superbai
        7
    superbai  
       2024-02-26 10:00:09 +08:00   ❤️ 1
    @Livid 推广引流
    wanniwa
        8
    wanniwa  
       2024-02-26 10:03:43 +08:00
    要是能放点 @Cacheable 和 @CacheEvict 等注解使用起来哪里不灵活,这个框架哪里比他更好用的地方就更好了
    Aresxue
        9
    Aresxue  
       2024-02-26 10:12:54 +08:00
    lyxeno
        10
    lyxeno  
       2024-02-26 10:14:18 +08:00
    过期配置是比 Spring Cache 灵活一点。不过你这个用方法签名作为 key 感觉会比统一的 Cachename 更难维护?
    ggfickle123
        11
    ggfickle123  
       2024-02-26 10:16:14 +08:00
    能不能解释下优化了 Spring Cache 的什么痛点呢
    heider
        12
    heider  
       2024-02-26 10:17:45 +08:00
    自己 AOP 封一个。。想怎么扩展怎么扩展 顶多 200 行代码
    zuozuomu
        13
    zuozuomu  
       2024-02-26 10:19:31 +08:00   ❤️ 3
    反而引用了一个个人开发的包,让项目更不稳定了。解决了 spring 比较稳定的痛点是吧?
    potatowish
        14
    potatowish  
       2024-02-26 10:24:11 +08:00 via iPhone
    要说到灵活,我宁可手写代码操作缓存,也不想加这些注解。实际业务中,设置缓存和移除缓存的粒度并不是在方法级别,要用到缓存注解,还要拆解出单独的函数。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1021 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 19:45 · PVG 03:45 · LAX 11:45 · JFK 14:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.