Springboot集成JetCache

本文介绍JetCache集成步骤与常见问题解决方案,包括配置、依赖引入及缓存注解使用。

        最近在学习缓存技术,暂时了解到可做缓存的有Spring Cache,mybatis自带的缓存和JetCache等等。因为JetCache是阿里系的,而且教程看起来也相当容易上手和简便,因为就先学习了JetCache,来记录下学到的东西。

        JetCache源码地址:

JetCache: JetCache 是一个基于 Java 的缓存系统封装,提供统一的 API 和注解来简化缓存的使用

首先需要确保电脑安装了redis并开启了redis。安装教程请看其他网友的贴子啦。

pom引入:

<dependency>
    <groupId>com.alicp.jetcache</groupId>
    <artifactId>jetcache-starter-redis</artifactId>
    <version>2.6.0</version>
</dependency>

启动和配置:

@SpringBootApplication
@EnableMethodCache(basePackages = "com.hyz.provider")
@EnableCreateCacheAnnotation
public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }
}

application.yml:

jetcache:
  statIntervalMinutes: 15
  areaInCacheName: false
  local:
    default:
      type: linkedhashmap
      keyConvertor: fastjson
      limit: 100
  remote:
    default:
      type: redis
      keyConvertor: fastjson
      valueEncoder: java
      valueDecoder: java
      poolConfig:
        minIdle: 5
        maxIdle: 20
        maxTotal: 50
      host: 127.0.0.1
      port: 6379

测试用例:

package com.hyz.provider.service;

import com.alicp.jetcache.anno.CacheInvalidate;
import com.alicp.jetcache.anno.CacheUpdate;
import com.alicp.jetcache.anno.Cached;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hyz.provider.entity.IdCard;
import com.hyz.provider.mapper.IdCardMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;


@Service
public class IdCardService extends ServiceImpl<IdCardMapper, IdCard> {

    @Autowired
    IdCardMapper idCardMapper;

    @Cached(name="idCardCache-", key="#id", expire = 3600,postCondition = "result!=null")
    public IdCard getById(String id){
        System.out.println("--查询详情--");
        LambdaQueryWrapper<IdCard> query=new LambdaQueryWrapper<>();
        query.eq(IdCard::getId,id);
        query.isNull(IdCard::getDeleteAt);
        return this.getOne(query);
    }
    
    @CacheUpdate(name="idCardCache-", key="#idCard.id", value="#idCard" , condition = "result == true")
    public Boolean create(IdCard idCard){
        //有个小问题,createAt时间没有更新到缓存,因为idCard没有传createAt
        return this.saveOrUpdate(idCard);
    }

    @CacheInvalidate(name="idCardCache-", key="#id",condition = "result == true")
    public Boolean deleteIdCard(String id){
        LambdaUpdateWrapper<IdCard> updateWrapper=new UpdateWrapper<IdCard>().lambda();
        updateWrapper.set(IdCard::getDeleteAt, LocalDateTime.now())
                .eq(IdCard::getId,id);
        return this.update(new IdCard(),updateWrapper);
    }
}

由于我的代码是集成了mybatis-plus,所以实际测试还是以自己为准就行。

@Cached用于创建一个缓存,@CacheUpdate用于更新缓存,@CacheInvalidate用于使缓存失效

        这里说说我遇到的两个问题,第一个问题就是,condition是判断什么情况下才执行该缓存,但我当时不知道如何通过condition获取方法的返回值,再去判断,这里谢谢这位网友的分享,我才知道写法,能够用result来获取返回值。

springcloud2 jetcache配置和使用总结_fengzhaoyang的专栏-优快云博客_jetcache配置

        第二个问题就是,一开始,我是通过另外一个方法去调用这个带有缓存注解的方法,但是测试下都不生效,代码例子如下:

    public void updateIdCard(IdCard idCard){
        this.create(idCard);
    }
    
    @CacheUpdate(name="idCardCache-", key="#idCard.id", value="#idCard" , condition = "result == true")
    public Boolean create(IdCard idCard){
        return this.saveOrUpdate(idCard);
    }

Controller调用了Service的updateIdCard方法的时候,缓存没有更新到,发现这种情况有两种解决办法,一种是在updateIdCard上也加上更新缓存的注解,一种是直接调用这个create方法。原因应该是和注解的特性有关,具体还要看看资料,这里就不多叙述了。

        以上就是一个比较基础的springboot集成JetCache方法,JetCache还有很多其他的用法,有兴趣的可以去其他网友的分享里看看了。

<think>我们正在讨论Spring Boot集成JetCacheJetCache是一个基于Java的缓存框架,支持多种缓存后端(如Redis、Tair等),并且提供了声明式缓存(类似于Spring Cache)的功能,同时支持本地缓存和远程缓存的多级缓存。 集成步骤: 1. 添加依赖 2. 配置JetCache 3. 使用注解(如@Cached, @CacheUpdate, @CacheInvalidate等)进行缓存操作 下面详细说明: 步骤1:添加依赖 在pom.xml中添加jetcache的starter依赖(以使用Redis作为远程缓存为例): ```xml <dependency> <groupId>com.alicp.jetcache</groupId> <artifactId>jetcache-starter-redis</artifactId> <version>2.6.2</version> <!-- 请使用最新版本 --> </dependency> ``` 如果你还需要本地缓存(比如Caffeine),可以添加: ```xml <dependency> <groupId>com.alicp.jetcache</groupId> <artifactId>jetcache-starter-redis</artifactId> <version>2.6.2</version> </dependency> <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> <version>2.9.3</version> <!-- 请使用最新版本 --> </dependency> ``` 注意:jetcache-starter-redis已经包含了jetcache-core和jetcache-anno,所以不需要重复添加。 步骤2:配置JetCache 在application.yml(或application.properties)中配置: 示例application.yml配置: ```yaml jetcache: statIntervalMinutes: 15 # 统计间隔,分钟 areaInCacheName: false # 是否在缓存名称前加上区域(area)作为前缀,默认true,这里设置为false(可选) local: default: type: caffeine # 本地缓存类型 keyConvertor: fastjson # 可选,key转换器,用于将key转换为字符串,默认是none remote: default: type: redis # 远程缓存类型 keyConvertor: fastjson # 可选 valueEncoder: java # 值编码方式,可选java或kryo valueDecoder: java poolConfig: minIdle: 5 maxIdle: 20 maxTotal: 50 host: 127.0.0.1 port: 6379 ``` 步骤3:启用JetCacheSpring Boot的启动类上添加@EnableMethodCache和@EnableCreateCacheAnnotation注解: ```java import com.alicp.jetcache.anno.config.EnableCreateCacheAnnotation; import com.alicp.jetcache.anno.config.EnableMethodCache; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @EnableMethodCache(basePackages = "com.example") // 指定扫描注解的包路径 @EnableCreateCacheAnnotation // 启用@CreateCache注解 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 步骤4:使用缓存注解 在Service层的方法上使用注解: - @Cached: 用于方法结果缓存 - @CacheUpdate: 更新缓存 - @CacheInvalidate: 删除缓存 示例: ```java import com.alicp.jetcache.anno.CacheInvalidate; import com.alicp.jetcache.anno.CacheUpdate; import com.alicp.jetcache.anno.Cached; import org.springframework.stereotype.Service; @Service public class UserServiceImpl implements UserService { @Override @Cached(name = "userCache.", key = "#id", expire = 3600) public User getUserById(Long id) { // 从数据库获取用户 return userDao.getUserById(id); } @Override @CacheUpdate(name = "userCache.", key = "#user.id", value = "#user") public void updateUser(User user) { userDao.updateUser(user); } @Override @CacheInvalidate(name = "userCache.", key = "#id") public void deleteUser(Long id) { userDao.deleteUser(id); } } ``` 注意:在@Cached注解中,name和key组合成完整的缓存key,name一般用来区分不同的缓存区域,可以以点结束,这样key就会直接拼接在后面。expire表示缓存过期时间,单位秒。 问题解释: 1. 为什么需要配置areaInCacheName?默认情况下,JetCache会在缓存key前面加上区域(area)名称,形成“区域:缓存名:key”的形式。如果设置为false,则不会添加区域前缀。 2. 本地缓存和远程缓存:可以同时配置,JetCache支持多级缓存(本地+远程),但需要配置缓存类型(type)为caffeine(本地)和redis(远程)。 3. 注解中的name和key:name是缓存实例的名称,key是SpEL表达式,用于动态生成缓存的键。 注意事项: - 确保Redis服务已启动,并且配置正确。 - 如果需要使用多级缓存(本地+远程),需要配置两个缓存实例(local和remote),并且在@Cached注解中指定cacheType为CacheType.BOTH(默认是REMOTE)。 - 使用@Cached注解的方法,参数需要可序列化(如果使用远程缓存),因为需要将参数作为key的一部分。 以上就是在Spring Boot集成JetCache的基本步骤。 §§相关问题§§: 1. JetCache支持哪些缓存类型? 2. 如何在JetCache中配置多级缓存(本地+远程)? 3. JetCache的@Cached注解有哪些常用属性? 4. 如何解决缓存穿透问题?</think>### Spring Boot集成JetCache详解 JetCache是阿里巴巴开源的通用缓存框架,支持本地缓存(如Caffeine)、远程缓存(如Redis)和多级缓存组合,提供声明式缓存注解和灵活的配置。 #### 集成步骤及代码示例 1. **添加依赖** ```xml <!-- pom.xml --> <dependencies> <dependency> <groupId>com.alicp.jetcache</groupId> <artifactId>jetcache-starter-redis</artifactId> <version>2.7.4</version> <!-- 使用最新版本 --> </dependency> <dependency> <groupId>com.alicp.jetcache</groupId> <artifactId>jetcache-starter-redis-springdata</artifactId> <!-- 适配Spring Data Redis --> <version>2.7.4</version> </dependency> </dependencies> ``` 2. **配置缓存(application.yml)** ```yaml jetcache: statIntervalMinutes: 15 # 监控统计间隔 areaInCacheName: false # 是否在key中包含area名称 local: default: type: caffeine # 本地缓存类型 keyConvertor: fastjson limit: 200 # 本地缓存最大元素数 remote: default: type: redis # 远程缓存类型 keyConvertor: fastjson valueEncoder: java # 序列化方式 valueDecoder: java poolConfig: minIdle: 5 maxTotal: 20 host: 127.0.0.1 # Redis地址 port: 6379 # 多级缓存配置(可选) multiLevel: - local: default - remote: default ``` 3. **启用JetCache** ```java @SpringBootApplication @EnableMethodCache(basePackages = "com.example.service") // 启用方法缓存 @EnableCreateCacheAnnotation // 启用@CreateCache注解 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 4. **使用缓存注解** ```java import com.alicp.jetcache.anno.*; @Service public class UserService { // 基础缓存(10分钟过期) @Cached(name = "userCache.", key = "#id", expire = 600) public User getUserById(Long id) { return userRepository.findById(id).orElse(null); } // 更新缓存 @CacheUpdate(name = "userCache.", key = "#user.id", value = "#user") public void updateUser(User user) { userRepository.save(user); } // 删除缓存 @CacheInvalidate(name = "userCache.", key = "#id") public void deleteUser(Long id) { userRepository.deleteById(id); } // 多级缓存示例(本地+远程) @Cached(cacheType = CacheType.BOTH, localLimit = 50, expire = 3600) public List<User> getActiveUsers() { return userRepository.findByActiveTrue(); } } ``` 5. **手动创建缓存实例** ```java @Service public class ProductService { @CreateCache(name = "productCache_", expire = 1200) private Cache<Long, Product> productCache; public Product getProduct(Long id) { return productCache.computeIfAbsent(id, key -> productRepository.findById(id).orElse(null) ); } } ``` #### 关键概念解释 1. **多级缓存** `CacheType.BOTH`:优先从本地缓存读取,未命中时查询远程缓存,最后回源到数据库。 2. **序列化方式** - `java`:JDK序列化(需实现`Serializable`) - `kryo`:更高效的二进制序列化(需添加`kryo`依赖) 3. **缓存穿透防护** JetCache内置`CachePenetrationProtect`注解,可配置超时自动刷新缓存: ```java @Cached(penetrationProtect = true, expire = 3600) public List<Item> getHotItems() { ... } ``` #### 常见问题解决 **问题1:缓存更新不一致** **原因**:直接操作数据库绕过缓存更新 **方案**:使用`@CacheUpdate`或`@CacheInvalidate`保证缓存一致性 **问题2:本地缓存内存溢出** **原因**:未限制本地缓存大小 **方案**:配置`jetcache.local.default.limit`限制元素数量 **问题3:Redis连接超时** **原因**:网络或连接池配置不当 **方案**:调整连接池参数: ```yaml jetcache: remote: default: poolConfig: maxWaitMillis: 2000 testWhileIdle: true ``` #### 性能优化建议 1. 高频读操作:使用`CacheType.BOTH`减少网络开销 2. 大数据缓存:配置`valueEncoder = kryo`减少存储体积 3. 缓存预热:结合`@PostConstruct`初始化热点数据 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值