发布时间:2019-09-20 07:36:53编辑:auto阅读(1973)
官网地址:http://×××w.ehcache.org/documentation/3.6/getting-started.html
根据官网的说明使用起来非常简单,尤其是在3.0之后, 不管事xml配置文件还是链式编码配置。
先看示例:
ResourcePoolsBuilder resourcePoolsBuilder = ResourcePoolsBuilder.newResourcePoolsBuilder().heap(20, MemoryUnit.MB).offheap(30, MemoryUnit.MB); CacheConfiguration<String, Object> cacheConfiguration = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, Object.class, resourcePoolsBuilder) .withValueSerializer(new PlainJavaSerializer<>(this.getClass().getClassLoader())) .withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofHours(24))).build(); org.ehcache.CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder() .withDefaultSizeOfMaxObjectSize(500, MemoryUnit.KB) .withDefaultSizeOfMaxObjectGraph(2000) .withCache(CACHE_NAME_CHINESE_DIC, cacheConfiguration) .withCache(CACHE_NAME_ENGLISH_DIC, cacheConfiguration) .build(true);
重要的几个知识点:
ehcache是分层缓存的
heap 堆内缓存,也就是存储在JVM内存中;
off heap 堆外缓存,非JVM单独非配的一部分内存。因此,设置的参数要与jvm启动参数相协调。
disk 磁盘缓存,也就是将缓存内容写入到磁盘文件中。
cluster 集群缓存,它是需要已cluster服务器来处同步存储这些数据。
注意:
1.heap是必须配置的;
2.disk tier不能与cluster tier共存,因为,它们回产生不一致;
3.个缓存tier是金字塔的配置,也就是 heap > off heap > disk > cluster,并且配置的大小是一次递增。
4.除了heap tier之外,其它层都必须设置key和value的序列化器和反序列化器。另外基础数据类型,已经实现其对相应的序列化/反序列化器。
ResourcePoolsBuilder是每个cache独立的,它仅仅只是配置信息。如:如果配置heap=20M,那么每个cache都有20M.
过期时间设置策略
如:withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofHours(24))
no expiry 永不过期
time-to-live 从缓存开始计算,所存储的时间
time-to-idle 最后一次使用后计算,所存储的时间
UserManagedCache
一个功能不需要太全,但能满足基本的缓存,则使用此类。
UserManagedCache<Long, String> userManagedCache = UserManagedCacheBuilder.newUserManagedCacheBuilder(Long.class, String.class).build(false); userManagedCache.init();
注:build(false)时,需要调用init()方法才有效。
此外,ehcache还有很多其他的设置,比如事务机制,集群,自定义线程池,自定义序列化器和反序列化器等等。在此就不在赘述,官网很详细。
springboot整合ehcache
由于版本的不同,之前的springboot集成的时3.0之前的jar, 但是从3.0之后,依赖地址有net.sfn.ehache.*改为org.apache.echache.*。因此,自己注入了sprintboot cacheManager的实现。
代码如下:
<dependency> <groupId>org.ehcache</groupId> <artifactId>ehcache</artifactId> <version>3.6.2</version> </dependency>
@Configuration @EnableCaching public class CacheConfig { private static final Logger LOGGER = LoggerFactory.getLogger(CacheConfig.class); private static final String CACHE_NAME_XXXX = "XXXX"; private static final String CACHE_NAME_YYYY = "YYYY"; @Bean public CacheManager cacheManager() { ResourcePoolsBuilder resourcePoolsBuilder = ResourcePoolsBuilder.newResourcePoolsBuilder().heap(20, MemoryUnit.MB).offheap(30, MemoryUnit.MB); CacheConfiguration<String, Object> cacheConfiguration = CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, Object.class, resourcePoolsBuilder) .withValueSerializer(new PlainJavaSerializer<>(this.getClass().getClassLoader())) .withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofHours(24))).build(); org.ehcache.CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder() .withDefaultSizeOfMaxObjectSize(500, MemoryUnit.KB) .withDefaultSizeOfMaxObjectGraph(2000) .withCache(CACHE_NAME_XXXX , cacheConfiguration) .withCache(CACHE_NAME_YYYY, cacheConfiguration) .build(true); return new CacheManager() { @Override public Cache getCache(String name) { org.ehcache.Cache<String, Object> heapEhcache = cacheManager.getCache(name, String.class, Object.class); return new Cache() { @Override public String getName() { return name; } @Override public Object getNativeCache() { return heapEhcache; } @Override public ValueWrapper get(Object key) { Object value = heapEhcache.get(String.valueOf(key)); return null == value ? null : () -> value; } @Override public <T> T get(Object key, Class<T> type) { Object value = heapEhcache.get(String.valueOf(key)); if (value != null && type != null && !type.isInstance(value)) { throw new IllegalStateException("Cached value is not of required type [" + type.getName() + "]: " + value); } return (T) value; } @Override public <T> T get(Object key, Callable<T> valueLoader) { try { return valueLoader.call(); } catch (Exception e) { LOGGER.error("ehcache valueLoader.call occur error", e); } return null; } @Override public void put(Object key, Object value) { heapEhcache.put(String.valueOf(key), value); } @Override public ValueWrapper putIfAbsent(Object key, Object value) { Object putIfAbsent = heapEhcache.putIfAbsent(String.valueOf(key), value); return putIfAbsent == null ? null : () -> putIfAbsent; } @Override public void evict(Object key) { heapEhcache.remove(String.valueOf(key)); } @Override public void clear() { heapEhcache.clear(); } }; } @Override public Collection<String> getCacheNames() { String[] cacheNames = {CACHE_NAME_XXXX , CACHE_NAME_YYYY}; return Arrays.asList(cacheNames); } }; } }
注意: 返回类型为ValueWrapper的Cache接口需要注意,源码提示:当返回为null说明缓存中没有此key,则直接返回null,然后就会从数据库中取数据。当有返回值时,说明缓存中有此key, 此时应该返回ValueWrapper的包裹类(包含了实际的返回值)。
上一篇: python requests模块详解
下一篇: 新浪微博爬虫设计(Python版)
47839
46383
37274
34725
29311
25968
24900
19946
19538
18019
5788°
6410°
5925°
5959°
7062°
5908°
5941°
6435°
6402°
7774°