在项目中想使用EhCache作为本地内存,而EhCache又存在这两个大版本,一个是2一个是3 。两者的区别很大,很容易在整合时踩到坑: 网上大多数(几乎全部) 整合都是基于EhCache2版本的,并且是通过xml的方式进行配置,如果在项目中用maven导入的EhCache3的话,整合方式会相差很多!
本文主要介绍如何去整合EhCache3和SpringCache。
当然,还是顺带简要提一下其他方式的使用,以形成对比。
不需要额外的配置,导包即可使用。直接看官网的实例,不赘述了。
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();
1.导入EhCache2的maven依赖
2.在application配置文件中配置:
spring:
cache:
type: ehcache
ehcache:
config: ehcache.xml
3.编写ehcache.xml配置文件,放置在resource目录下
4.@EnableCaching
至此就整合完毕,即可在项目中使用@Cacheable等注解。
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官网。
为什么整合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的区别,以前我从未区分过这一点,看了之后有种醍醐灌顶的感觉。在这里也分享一下给大家:
简单总结一下就是: