今天是:
带着程序的旅程,每一行代码都是你前进的一步,每个错误都是你成长的机会,最终,你将抵达你的目的地。
title

Springboot 整合 Caffeine 缓存

1.Caffeine是什么


Caffeine是基于Java 8的高性能缓存库,可提供接近最佳的命中率。

缓存类似于ConcurrentMap,但不完全相同。最根本的区别是ConcurrentMap会保留添加到其中的所有元素,直到将其明确删除为止。另一方面,通常将缓存配置为自动移除条目,以限制其内存占用量。在某些情况下,由于LoadCache或AsyncLoadingCache不会自动移除缓存,因此即使移除缓存也可能会很有用。

Caffeine提供灵活的构造来创建具有以下功能组合的缓存:

自动将条目自动加载到缓存中,可以选择异步加载
基于频率和新近度超过最大值时基于大小的过期策略
自上次访问或上次写入以来测得的基于时间的条目到期
发生第一个陈旧的条目请求时,异步刷新
键自动包装在弱引用中
值自动包装在弱引用或软引用中
逐出(或以其他方式删除)条目的通知
写入传播到外部资源
缓存访问统计信息的累积
为了改善集成,扩展模块中提供了JSR-107 JCache和Guava适配器。 JSR-107标准化了基于Java 6的API,以牺牲功能和性能为代价,最大限度地减少了供应商特定的代码。 Guava的Cache是​​其前身的库,适配器提供了一种简单的迁移策略。

2.SpringBoot中配置Caffeine

spring配置配置缓存,需要配置对应的缓存管理器,然后再需要缓存的地方加上缓存注解

引入需要的包,这里使用的时gradle

    compile group: 'org.springframework.boot', name: 'spring-boot-starter-cache', version: '2.4.1'
    compile group: 'com.github.ben-manes.caffeine', name: 'caffeine', version: '2.8.8'

配置缓存管理器

@Configuration
@EnableCaching
public class CacheConfig {

   @Bean
    public Caffeine caffeineCache() {
        return Caffeine.newBuilder()
                .expireAfterWrite(60, TimeUnit.MINUTES);
    }

    @Bean
    public CacheManager cacheManager(Caffeine caffeine) {
        CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
        caffeineCacheManager.setCaffeine(caffeine);
        return caffeineCacheManager;
    }
}

 

接下来我们创建一张表,然后使用Caffeine缓存

 

CREATE TABLE `spring_cache`  (
  `id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `cache_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `cache_type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;


-- ----------------------------
-- Records of spring_cache
-- ----------------------------
INSERT INTO `spring_cache` VALUES ('1', 'caffeine', 'caffeine');
INSERT INTO `spring_cache` VALUES ('2', 'guava', 'guava');
INSERT INTO `spring_cache` VALUES ('3', 'EhCache', 'EhCache');
INSERT INTO `spring_cache` VALUES ('4', 'Infinispan', 'Infinispan');

 

使用缓存注解配置,再springboot应用中测试

 

@Service
@Slf4j
@CacheConfig(cacheNames="caffeine")
public class SpringCacheServiceImpl extends BaseAbstractService<SpringCache,String> implements SpringCacheService<SpringCache,String> {

    private static Logger logger = LoggerFactory.getLogger(SpringCacheServiceImpl.class);


    @Autowired
    SpringCacheRepository springCacheRepository;


    @Cacheable(key = "#id")
    public SpringCache getCache(String id){
        logger.info("get spring caffeine cache,id=[{}]",id);
        return springCacheRepository.findById(id).get();
    }

    @Override
    @CacheEvict(key = "#id")
    public void removeCache(String id) {

        springCacheRepository.deleteById(id);
        logger.info("remove spring caffeine cache,id=[{}]",id);
    }

    @Override
    @CachePut( key = "#sc.id")
    public void saveCache(SpringCache sc) {

        SpringCache newSc=springCacheRepository.saveAndFlush(sc);
        logger.info("put spring caffeine cache,id=[{}]",sc.getId());
    }

}

 

 注意springboot启动应用中加@EnableCaching。

 

   
//实现CommandLineRunner接口
 public void run(String... args) throws Exception {
        logger.info("spring boot runner");
        logger.info("Spring Boot Caffeine Caching Example Configuration");
        springCacheService.getCache("1");
        springCacheService.getCache("2");
        springCacheService.getCache("3");
        springCacheService.getCache("4");

        Cache cache=cacheManager.getCache("caffeine");
        springCacheService.getCache("1");
        springCacheService.getCache("2");
    }

从控制台可以看出前四条发出sql查询,后面两条没有,证明是读取了缓存

10:20:56.668 [restartedMain] INFO  c.zlennon.web.ZlennonWebApplication - Spring Boot Caffeine Caching Example Configuration
10:20:56.785 [restartedMain] INFO  c.z.c.s.impl.SpringCacheServiceImpl - get spring caffeine cache,id=[1]
10:20:56.921 [restartedMain] DEBUG org.hibernate.SQL - select springcach0_.id as id1_9_0_, springcach0_.cache_name as cache_na2_9_0_, springcach0_.cache_type as cache_ty3_9_0_ from spring_cache springcach0_ where springcach0_.id=?
10:20:57.016 [restartedMain] INFO  c.z.c.s.impl.SpringCacheServiceImpl - get spring caffeine cache,id=[2]
10:20:57.017 [restartedMain] DEBUG org.hibernate.SQL - select springcach0_.id as id1_9_0_, springcach0_.cache_name as cache_na2_9_0_, springcach0_.cache_type as cache_ty3_9_0_ from spring_cache springcach0_ where springcach0_.id=?
10:20:57.021 [restartedMain] INFO  c.z.c.s.impl.SpringCacheServiceImpl - get spring caffeine cache,id=[3]
10:20:57.023 [restartedMain] DEBUG org.hibernate.SQL - select springcach0_.id as id1_9_0_, springcach0_.cache_name as cache_na2_9_0_, springcach0_.cache_type as cache_ty3_9_0_ from spring_cache springcach0_ where springcach0_.id=?
10:20:57.027 [restartedMain] INFO  c.z.c.s.impl.SpringCacheServiceImpl - get spring caffeine cache,id=[4]
10:20:57.029 [restartedMain] DEBUG org.hibernate.SQL - select springcach0_.id as id1_9_0_, springcach0_.cache_name as cache_na2_9_0_, springcach0_.cache_type as cache_ty3_9_0_ from spring_cache springcach0_ where springcach0_.id=?
同样我们可以查看缓存管理器的缓存

接下来如果我们执行删除和增加操作,会有相应的缓存删除和增加

        springCacheService.removeCache("4");
        SpringCache sc =new SpringCache();
        sc.setId("4");
        sc.setCacheName("Infinispan");
        sc.setCacheType("Infinispan");
        springCacheService.saveCache(sc);

3.原理探索

分享到:

专栏

类型标签

网站访问总量