文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

ehcache 3.* 使用介绍

2023-01-31 07:11

关注

官网地址: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是分层缓存的

TiersHierarchy.png

  • 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))

  1. no expiry 永不过期

  2. time-to-live 从缓存开始计算,所存储的时间

  3. 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的包裹类(包含了实际的返回值)。


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯