SpringCache整合EhCache2和EhCache3(JCache)

简介

在项目中想使用EhCache作为本地内存,而EhCache又存在这两个大版本,一个是2一个是3 。两者的区别很大,很容易在整合时踩到坑: 网上大多数(几乎全部) 整合都是基于EhCache2版本的,并且是通过xml的方式进行配置,如果在项目中用maven导入的EhCache3的话,整合方式会相差很多!
本文主要介绍如何去整合EhCache3和SpringCache。
当然,还是顺带简要提一下其他方式的使用,以形成对比。

单独使用EhCache

不需要额外的配置,导包即可使用。直接看官网的实例,不赘述了。

CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder() 
    .withCache("preConfigured",
        CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(10))) 
    .build(); 
cacheManager.init(); 

Cache<Long, String> preConfigured =
    cacheManager.getCache("preConfigured", Long.class, String.class); 

Cache<Long, String> myCache = cacheManager.createCache("myCache", 
    CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(10)));

myCache.put(1L, "da one!"); 
String value = myCache.get(1L); 

cacheManager.removeCache("preConfigured"); 

cacheManager.close(); 

整合EhCache2和SpringCache

1.导入EhCache2的maven依赖
2.在application配置文件中配置:

spring:
  cache:
    type: ehcache
  ehcache:
  	config: ehcache.xml

3.编写ehcache.xml配置文件,放置在resource目录下
4.@EnableCaching
至此就整合完毕,即可在项目中使用@Cacheable等注解。

整合EhCache3和SpringCache

1.导入EhCache3的maven依赖
2.在application配置文件中配置:

spring:
  cache:
    type: jcache

千万要注意,是jcache类型!!!不是ehcache!!!
3.编写配置类

package top.dumbzarro.greensource.coupon.config;

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.jcache.JCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import top.dumbzarro.greensource.coupon.entity.CouponEntity;

import javax.cache.CacheManager;
import javax.cache.Caching;
import javax.cache.configuration.MutableConfiguration;
import javax.cache.expiry.CreatedExpiryPolicy;
import javax.cache.expiry.Duration;
import javax.cache.spi.CachingProvider;

/**
 * Description: 整合 SpringCache 和 EhCache
 */
@EnableCaching
@Configuration
public class MyCacheConfig {
    
    
    @Bean
    JCacheCacheManager ehcacheConfiguration() {
    
    

        // 缓存配置
        MutableConfiguration<Integer, CouponEntity> configuration = new MutableConfiguration<Integer, CouponEntity>()
                .setTypes(Integer.class, CouponEntity.class)
                .setStoreByValue(false)
                .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(Duration.ONE_MINUTE));

        // cacheManager
        CachingProvider cachingProvider = Caching.getCachingProvider();
        CacheManager cacheManager = cachingProvider.getCacheManager();
        cacheManager.createCache("coupon", configuration);

        // jcache
        JCacheCacheManager JCache = new JCacheCacheManager();
        JCache.setCacheManager(cacheManager);

        return JCache;
    }
}

千万千万千万要注意各个类所在的包,晚上很多整合教程都省略了引入的类所在的包,包括官方,这给一些不太熟悉的小白(比如说我)整合的时候带来很大的困扰。
光是cacheManager就有三个
在这里插入图片描述
整合时使用的类的包我都列出来了,都是在javax包,具体原因下面再讲。

4.@EnableCaching
至此就整合完毕,即可在项目中使用@Cacheable等注解。

当然,以上配置只是EhCache的其中一种简化配置方法,EhCache3仍然可以使用xml配置进行整合,具体方法参照Ehcache官网。

JCache aka JSR-107

为什么整合EhCache3的时候是在配置中配置的spring.cache.tpye是jcache而不是ehcache呢?
我们看看Spring官网中的介绍,需要主义的是SpringCache并不像Spring Date、Spring Security一样是另外的框架,它被包含在Spring Framework的Integration模块之中
在这里插入图片描述
官网原文如下:

Spring provides a few implementations of that abstraction: JDK java.util.concurrent.ConcurrentMap based caches, Ehcache 2.x, Gemfire cache, Caffeine, and JSR-107 compliant caches (such as Ehcache 3.x). See Plugging-in Different Back-end Caches for more information on plugging in other cache stores and providers.

意思就是SpringCache提供了一些实现帮助我们整合 Ehcache 2.x、Caffeine、JSR-107(例如Ehcache3)等框架。也就是说,在我们整合Ehcache3的时候我们需要整合的是JSR-107,而不是Ehcache。
在这里插入图片描述
官网提供了整合到Spring的方法,但是我们使用的是springboot,我们想让其自动注入。
具体要怎么整合到Springboot呢,官网没有说,但是我们可以看到,真好到Springboot中就是提供一个cacheManager到容器之中,而SpringCache为JSR-107默认提供了一个实现,在JCache包下,叫JCacheCacheManger。
第一时间就想到我们自己创建一个然后使用@Bean丢到容器中就可以了
这个类也很好创建,直接new JCacheCacheManager();无参就可以构造。运行起来之后也确实不会报错“找不到可用的cacheManager”了,但是相应的我们发现这个manager不提供任何createCache的方法,他只支持去设置cacheManager,和获取cacheManager,显而易见的,这个JCacheCacheManager实际上是一个门面,具体的cacheManager还要我们去实现,而它设置cacheManager类型是在javax包下面的,这也很容易让人知道,SpringCache在这部分的实现原理是SPI机制(如果你不太清楚什么是SPI机制,那么可以想想同样在javax包下的sql包)
所以总结一下就是,目前我们需要去构造一个cacheManager,具体的实现类由EhCache提供,我们已经通过maven导入,现在就是使用javax.cache中定义的接口进行实例化一个cacheManager。
当然,具体如何构造,我们其实不太清楚,这也不属于SpringCache范畴的内容,在SpringCache文档中当然找不到,于是我们可以合理的猜测,EhCache3的官网应该有相关的实例。一找还真有。
在这里插入图片描述
接下来的内容就不赘述了,官方文档写的也听清楚的了。

写在最后

随着学习的知识逐渐变得不是那么的"热门",相关的博客的帮助有时反而会形成一定的误导,可能是版本问题、也可能是其他的问题,总之就是会发现对官方文档的依赖会变得越来越重。本次整合其实因为是个人练手,对于性能、特性之类的没有太大的要求,属于能用就行的那种,而这次整合出现的问题其实完全可以只动一动小手,将版本从三改成二,就可以很轻松的解决问题了。然而这次强迫自己去阅读官方文档,去自己根据官方文档进行整合,因为可以预见的是这是以后不可或缺的能力。经过几个小时的阅读和尝试,终于整合成功了,很有成就感,并且所收获的也远比整合成功这个结果多——对英文和官方文档不再畏惧了。
除此之外还收获了一点小的知识点,例如SpringCache文档中有一小段专门解释了一下Buffer和Cache的区别,以前我从未区分过这一点,看了之后有种醍醐灌顶的感觉。在这里也分享一下给大家:
在这里插入图片描述
简单总结一下就是:

  • buffer是通过化零为整的方式去缓解快速设备需要等待慢速设备的问题从而提高性能
  • 相同的数据在buffer中只取一次。
  • cache是通过让数据被快速方式读取的方式从而提高性能
  • 相同的数据在cache中被多次读取。

猜你喜欢

转载自blog.csdn.net/weixin_45654405/article/details/127351986