当前位置: 首页 > 工具软件 > Caffeine > 使用案例 >

Springboot 集成 Caffeine

乐正迪
2023-12-01

Springboot 集成 Caffeine

前言:Caffeine 是个高性能的开源 Java 内存缓存库,具有较高的命中率和出色的并发能力。在 Spring Boot 中集成也非常简单,提供了各种开箱既用的工具。

Caffeine 并不是分布式缓存.

1.引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
</dependency>
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>2.8.0</version>
</dependency>

2.添加配置文件

spring.cache.cache-names=IZUUL
spring.cache.caffeine.spec=initialCapacity=50,maximumSize=500,expireAfterWrite=5s
spring.cache.type=caffeine

Caffeine配置说明:

1、initialCapacity=[integer]: 初始的缓存空间大小
2、maximumSize=[long]: 缓存的最大条数
3、maximumWeight=[long]: 缓存的最大权重
4、expireAfterAccess=[duration]: 最后一次写入或访问后经过固定时间过期
5、expireAfterWrite=[duration]: 最后一次写入后经过固定时间过期
6、refreshAfterWrite=[duration]: 创建缓存或者最近一次更新缓存后经过固定的时间间隔,刷新缓存
7、weakKeys: 打开key的弱引用
8、weakValues:打开value的弱引用
9、softValues:打开value的软引用
1o、recordStats:开发统计功能

注意:

1、expireAfterWrite和expireAfterAccess同时存在时,以expireAfterWrite为准。
2、maximumSize和maximumWeight不可以同时使用
3、weakValues和softValues不可以同时使用

3、通过配置注入bean的方式配置(与xml配置文件二选一)

@Configuration
public class CaffeineConfig {
    @Bean
    public CacheManager caffeineCacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();

        List<CaffeineCache> caffeineCaches = new ArrayList<>();

        for (CacheType cacheType : CacheType.values()) {
            caffeineCaches.add(new CaffeineCache(cacheType.name(),
                    Caffeine.newBuilder()
                            .expireAfterWrite(cacheType.getExpires(), TimeUnit.SECONDS)
                            .build()));
        }

        cacheManager.setCaches(caffeineCaches);

        return cacheManager;
    }
}

4、创建枚举类

加入过期时间expires, 分别设置IZUUl消亡时间是 10s, MUMU 消亡时间 5s

public enum CacheType {

    IZUUL(10),//消亡时间

    MUMU(5);

    private int expires;

    CacheType(int expires) {
        this.expires = expires;
    }

    public int getExpires() {
        return expires;
    }
}

5、创建service类

@Service
@Slf4j
public class CaffeineService {

    private final static Logger log = LoggerFactory.getLogger(CaffeineService.class);

	@Autowired
    private CouponUseRecordMapper couponUseRecordMapper;
    @Autowired
    private FullReductionProductstoreRelaMapper fullReductionProductMapper;

/**
 * 根据用户id和优惠券id获取该用户的优惠券记录
 *
 * @param userId   用户id
 * @param couponId 优惠券id
 * @return
 */
@Cacheable(value = "IZUUL", key = "#userId.concat(#couponId)")
public long couponUseRecordCount(String userId, String couponId) {
    CouponUseRecordCriteria qr = new CouponUseRecordCriteria();
    qr.or().andUserIdEqualTo(userId).andCouponIdEqualTo(couponId)
            .andCreateTimeGreaterThanOrEqualTo(Utils.getStartTime()).andCreateTimeLessThanOrEqualTo(Utils.getEndTime());
    Long i = this.couponUseRecordMapper.countByExample(qr);
    log.info("********调用了优惠券使用记录的缓存,用户id{},优惠券id{}********",userId,couponId);
    return i;
}

/**
 * 根据优惠券id和门店code获取满减券门店产品数据对应的关系
 *
 * @param couponId  优惠券id
 * @param storeCode 门店code
 * @param fullReduction  满减类型
 * @return
 */
@Cacheable(value = "IZUUL", key = "#couponId.concat(#storeCode).concat(#fullReduction)")
public List<FullReductionProductstoreRela> getFullReductionList(String couponId, String storeCode, String fullReduction) {
    FullReductionProductstoreRelaCriteria qr = new FullReductionProductstoreRelaCriteria();
    qr.or().andCouponIdEqualTo(couponId).andStoreCodeEqualTo(storeCode);
    List<FullReductionProductstoreRela> list = this.fullReductionProductMapper.selectByExample(qr);
    log.info("******调用了满减券门店产品数据对应关系的缓存,优惠券id{},门店编码{},满减类型{}*******",couponId,storeCode,fullReduction);
    return list;
}

}

6、controller层调用这两个方法

@RestController
public class CaffeineController {

    @Autowired
    private CaffeineService caffeineService;

@PostMapping("/cache-izuul/query") 
public boolean isUseCouponNums(
  @RequestParam(required = true)User user, 
  @RequestParam(required = true)ValueCoupon coupon
) {
    long i = caffeineService.couponUseRecordCount(user.getUserId(), coupon.getCouponId());
    if (i < coupon.getUseNumber()) {
       return true;
    }
    return false;
}
  
@PostMapping("/cache-izuul/query2")
public FullReductionProductstoreRela queryFullReductionProductstoreRela(
  @RequestParam(required = true) String storeCode, 
  @RequestParam(required = true)String couponId
) {
    List<FullReductionProductstoreRela> list = caffeineService.getFullReductionList(couponId, storeCode,"FULL_REDUCTION");
    if (CollectionUtils.isNotEmpty(list)) {
        return list.get(0);
    } else {
        return null;
    }
}
   
}

因为最近业务中涉及的查询操作非常多,所以就想到引入缓存这一操作去减轻访问数据库的压力,在网上看了一下相关文章,感觉还是相对比较简单且实用的,所以就简单整理了一下!如果有哪里存在缺陷,望大佬们多多指教!

 类似资料: