Java Cache 缓存方案详解及代码-Ehcache

简介: Java Cache 缓存方案详解及代码-Ehcache

一、Spring缓存概念

Spring从3.1开始定义了 org.springframework.cache.Cache 和 org.springframework.cache.CacheManager 接口来统一不同的缓存技术; 并支持使用 JCache(JSR-107) 注解简化我们开发。

常用的缓存实现有 RedisCache 、EhCache、ConcurrentMapCache 、Guava Cache(谷歌)等。

Spring Cache 介绍

Spring Cache是一个框架,实现了基于注解的缓存功能,只需要简单的加一个注解,就能实现缓存功能

Spring Cache提供了一层抽象,底层可以切换不同的Cache实现,具体是通过CacheManager接口来统一不同的缓存技术

针对于不同的缓存技术需要实现不同的CacheManager:

CacheManager

描述

EhCacheCacheManager

使用EhCache作为缓存技术

GuavaCacheManager

使用Google的GuavaCache作为缓存技术

RedisCacheManager

使用Redis作为缓存技术

Spring Cache 常用注解

我们来介绍Spring Cache用于缓存的常用的四个注解:

注解

说明

@EnableCaching

开启缓存注解功能

@Cacheable

在方法执行前先查看缓存中是否存有数据,如果有数据直接返回数据;如果没有,调用方法并将返回值存入缓存

@CachePut

将方法的返回值放到缓存

@CacheEvict

将一条或多条从缓存中删除

在Spring项目中,使用缓存技术只需要导入相关缓存技术的依赖包,并在启动类上加上@EnableCaching开启缓存支持即可

二、Ehcache介绍

 EhCache 是一个纯Java的进程内缓存管理框架,属于开源的Java分布式缓存框架,主要用于通用缓存,Java EE和轻量级容器,是从 Hibernate 的缓存开始的。

目前版本已到了Ehcache 3.10,Ehcache 3引入了以下内容:

  • 改进的 API,利用 Java 泛型并简化缓存交互,
  • 与javax.cache API (JSR-107)完全兼容,
  • 堆下存储功能,包括仅堆下缓存,
  • 开箱即用的Spring Caching和Hibernate集成,这要归功于javax.cache支持

1、 Ehcache特性:

1、快速轻量: Ehcache 是最快的 Java 缓存之一,很小的 jar 包

2、伸缩性:缓存在内存和磁盘存储可以伸缩到数 G

3、灵活性:Ehcache 1.2 具备对象 API 接口和可序列化 API 接口。

4、标准支持 Ehcache 提供了对 JSR107 JCACHE API 最完整的实现

5、可扩展性 监听器可以插件化

6、应用持久化 在 VM 重启后,持久化到磁盘的存储可以复原数据

官网:Ehcache

2、 Ehcache 的加载模块列表

ehcache-core:API,标准缓存引擎,RMI 复制和 Hibernate 支持

ehcache:分布式 Ehcache,包括 Ehcache 的核心和 Terracotta 的库

ehcache-monitor:企业级监控和管理

ehcache-web:为 Java Servlet Container 提供缓存、gzip 压缩支持的 filters

ehcache-jcache:JSR107 JCACHE 的实现

ehcache-jgroupsreplication:使用 JGroup 的复制

ehcache-jmsreplication:使用 JMS 的复制

ehcache-openjpa:OpenJPA 插件

ehcache-server:war 内部署或者单独部署的 RESTful cache server

ehcache-unlockedreadsview:允许 Terracotta cache 的无锁读

ehcache-debugger:记录 RMI 分布式调用事件

Ehcache for Ruby:Jruby and Rails 支持

3、核心定义

  • cache manager:缓存管理器,以前是只允许单例的,不过现在也可以多实例了
  • cache:缓存管理器内可以放置若干 cache,存放数据的实质,所有 cache 都实现了 Ehcache 接口
  • element:单条缓存数据的组成单位
  • system of record(SOR):可以取到真实数据的组件,可以是真正的业务逻辑、外部接口调用、存放真实数据的数据库等等,缓存就是从 SOR 中读取或者写入到 SOR 中去的

Ehcache 支持的数据存储包括:

  • 堆上存储 - 利用 Java 的堆上 RAM 内存来存储缓存条目。此层使用与 您的 Java 应用程序,所有这些应用程序都必须由 JVM 垃圾回收器扫描。您的 JVM 堆空间越多 利用,应用程序性能受垃圾回收暂停的影响就越大。这家商店是 速度极快,但通常是您最有限的存储资源。
  • 堆外存储 - 大小仅受可用 RAM 的限制。 不受 Java 垃圾回收 (GC) 的约束。 非常快,但比堆上存储慢,因为在存储和重新访问数据时,必须将数据移入和移出 JVM 堆。
  • 磁盘存储 - 利用磁盘(文件系统)存储缓存条目。 这种类型的存储资源通常非常丰富,但比基于 RAM 的存储慢得多。至于所有使用磁盘的应用程序 存储时,建议使用快速专用的磁盘来优化吞吐量。
  • 群集存储 - 此数据存储是远程服务器上的缓存。 远程服务器可以选择具有故障转移服务器,以提供改进的高可用性。 由于群集存储会因网络延迟以及建立客户端/服务器一致性等因素而带来性能损失, 从本质上讲,此层比本地堆外存储慢。

开发实例:

引入依赖:

<dependency>
      <groupId>org.ehcache</groupId>
      <artifactId>ehcache</artifactId>
      <version>3.10.0</version>
    </dependency>

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" name="defaultCache">
    <diskStore path="../temp/bojun/ehcache" />
    <!-- 默认缓存配置. -->
    <defaultCache maxEntriesLocalHeap="100" eternal="false" timeToIdleSeconds="1800" timeToLiveSeconds="3600"
        overflowToDisk="false" maxEntriesLocalDisk="100000" />
    <cache name="SystemAuthorizingRealm" maxEntriesLocalHeap="2000"
           eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0"
           overflowToDisk="false" statistics="true">
    </cache>
    <cache name="shiro-activeSessionCache" maxEntriesLocalHeap="2000"
           eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0"
           overflowToDisk="false" statistics="true">
    </cache>
    <!-- 系统缓存 -->
    <cache name="sysCache" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="false"/>
    <cache name="cmsCache" maxEntriesLocalHeap="3000" eternal="false" overflowToDisk="false"/>
    <cache name="captchaCache" maxEntriesLocalHeap="3000" timeToLiveSeconds="300" eternal="false" overflowToDisk="false"/>
    <!-- 用户缓存 -->
    <cache name="userCache" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="false"/>
    <!-- 工作流模块缓存 -->
    <cache name="actCache" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="false"/>
    <cache name="sys.config" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="false"/>
    <!-- 系统活动会话缓存 -->
    <cache name="activeSessionsCache" maxEntriesLocalHeap="10000" overflowToDisk="false"
           eternal="false" timeToLiveSeconds="0" timeToIdleSeconds="0"
           diskPersistent="true" diskExpiryThreadIntervalSeconds="600"/>
</ehcache>

配置类代码:

@ConditionalOnProperty(name = "spring.cache.type", havingValue = "ehcache")
@Configuration
@EnableCaching//标注启动缓存.
public class CacheConfig {
    /**
     * @param ehCacheManagerFactoryBean
     * @return
     */
    @Bean
    public EhCacheCacheManager ehCacheCacheManager(EhCacheManagerFactoryBean ehCacheManagerFactoryBean){
        System.out.println("CacheConfiguration.ehCacheCacheManager()");
        return new EhCacheCacheManager(ehCacheManagerFactoryBean.getObject());
    }
    /*
     * 据shared与否的设置,
     * Spring分别通过CacheManager.create()
     * 或new CacheManager()方式来创建一个ehcache基地.
     */
    @Bean
    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean(){
        System.out.println("CacheConfiguration.ehCacheManagerFactoryBean()");
        EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean ();
        cacheManagerFactoryBean.setShared(true);
        return cacheManagerFactoryBean;
    }
}

工具类:

public class CacheUtils {
private static CacheManager cacheManager = SpringContextHolder.getBean(CacheManager.class);
    private static final String SYS_CACHE = "sysCache";
    /**
     * 获取SYS_CACHE缓存
     *
     * @param key
     * @return
     */
    public static Object get(String key) {
        return get(SYS_CACHE, key);
    }
    /**
     * 获取SYS_CACHE缓存
     *
     * @param key
     * @param defaultValue
     * @return
     */
    public static Object get(String key, Object defaultValue) {
        Object value = get(key);
        return value != null ? value : defaultValue;
    }
    /**
     * 写入SYS_CACHE缓存
     *
     * @param key
     * @return
     */
    public static void put(String key, Object value) {
        put(SYS_CACHE, key, value);
    }
    /**
     * 从SYS_CACHE缓存中移除
     *
     * @param key
     * @return
     */
    public static void remove(String key) {
        remove(SYS_CACHE, key);
    }
    /**
     * 获取缓存
     *
     * @param cacheName
     * @param key
     * @return
     */
    public static Object get(String cacheName, String key) {
        if( getCache(cacheName).get(key) == null){
            return null;
        }else {
            return getCache(cacheName).get(key).get();
        }
    }
    /**
     * 获取缓存
     *
     * @param cacheName
     * @param key
     * @param defaultValue
     * @return
     */
    public static Object get(String cacheName, String key, Object defaultValue) {
        Object value = get(cacheName, key);
        return value != null ? value : defaultValue;
    }
    /**
     * 写入缓存
     *
     * @param cacheName
     * @param key
     * @param value
     */
    public static void put(String cacheName, String key, Object value) {
        getCache(cacheName).put(key, value);
    }
    /**
     * 从缓存中移除
     *
     * @param cacheName
     * @param key
     */
    public static void remove(String cacheName, String key) {
        getCache(cacheName).evict(key);
    }
    /**
     * 获得一个Cache,没有则显示日志。
     *
     * @param cacheName
     * @return
     */
    private static Cache getCache(String cacheName) {
        Cache cache = cacheManager.getCache(cacheName);
        if (cache == null) {
            throw new RuntimeException("当前系统中没有定义“" + cacheName + "”这个缓存。");
        }
        return cache;
    }
}

测试代码:

@Cacheable(key="'user_'+#id",value="userCache")
    public User getUserById(String id){     
        return userDao.findById(id);    }

这是一个cache框架,可以根据需要引入不同的cache实现方案


📢文章下方有交流学习区!一起学习进步!也可以前往官网,加入官方微信交流群💪💪💪

📢创作不易,如果觉得文章不错,可以点赞👍收藏📁评论📒

📢你的支持和鼓励是我创作的动力❗❗❗  

官网Doker 多克;官方旗舰店官方旗舰店  全品优惠

目录
相关文章
|
7月前
|
机器学习/深度学习 JSON Java
Java调用Python的5种实用方案:从简单到进阶的全场景解析
在机器学习与大数据融合背景下,Java与Python协同开发成为企业常见需求。本文通过真实案例解析5种主流调用方案,涵盖脚本调用到微服务架构,助力开发者根据业务场景选择最优方案,提升开发效率与系统性能。
1732 0
|
8月前
|
Cloud Native 前端开发 Java
WebAssembly 与 Java 结合的跨语言协作方案及性能提升策略研究
本文深入探讨了WebAssembly与Java的结合方式,介绍了编译Java为Wasm模块、在Java中运行Wasm、云原生集成等技术方案,并通过金融分析系统的应用实例展示了其高性能、低延迟、跨平台等优势。结合TeaVM、JWebAssembly、GraalVM、Wasmer Java等工具,帮助开发者提升应用性能与开发效率,适用于Web前端、服务器端及边缘计算等场景。
305 0
|
6月前
|
缓存 并行计算 监控
vLLM 性能优化实战:批处理、量化与缓存配置方案
本文深入解析vLLM高性能部署实践,揭秘如何通过continuous batching、PagedAttention与前缀缓存提升吞吐;详解批处理、量化、并发参数调优,助力实现高TPS与低延迟平衡,真正发挥vLLM生产级潜力。
1503 0
vLLM 性能优化实战:批处理、量化与缓存配置方案
|
7月前
|
缓存 监控 Kubernetes
Java虚拟机内存溢出(Java Heap Space)问题处理方案
综上所述, 解决Java Heap Space溢出需从多角度综合施策; 包括但不限于配置调整、代码审查与优化以及系统设计层面改进; 同样也不能忽视运行期监控与预警设置之重要性; 及早发现潜在风险点并采取相应补救手段至关重要.
929 17
|
7月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
|
8月前
|
缓存 监控 Linux
Linux系统清理缓存(buff/cache)的有效方法。
总结而言,在大多数情形下你不必担心Linux中buffer与cache占用过多内存在影响到其他程序运行;因为当程序请求更多内存在没有足够可用资源时,Linux会自行调整其占有量。只有当你明确知道当前环境与需求并希望立即回收这部分资源给即将运行重负载任务之前才考虑上述方法去主动干预。
2207 10
|
9月前
|
缓存 Java 数据库
Java 项目分层架构实操指南及长尾关键词优化方案
本指南详解基于Spring Boot与Spring Cloud的Java微服务分层架构,以用户管理系统为例,涵盖技术选型、核心代码实现、服务治理及部署实践,助力掌握现代化Java企业级开发方案。
398 2
|
8月前
|
缓存 运维 安全
WordPress安全加速:Cloudflare + Nginx缓存优化方案
本文介绍如何通过Cloudflare与Nginx优化WordPress网站性能,涵盖静态资源长期缓存、动态页面智能缓存及敏感路径保护,提升加载速度并保障后台安全。适用于使用Cloudflare与Nginx环境的WordPress站点。
389 0
|
10月前
|
安全 Java Docker
Docker 部署 Java 应用实战指南与长尾优化方案
本文详细介绍了Docker容器化部署Java应用的最佳实践。首先阐述了采用多阶段构建和精简JRE的镜像优化技术,可将镜像体积减少60%。其次讲解了资源配置、健康检查、启动优化等容器化关键配置,并演示了Spring Boot微服务的多模块构建与Docker Compose编排方案。最后深入探讨了Kubernetes生产部署、监控日志集成、灰度发布策略以及性能调优和安全加固措施,为Java应用的容器化部署提供了完整的解决方案指南。文章还包含大量可落地的代码示例,涵盖从基础到高级的生产环境实践。
641 3
|
9月前
|
JavaScript Java Go
Go、Node.js、Python、PHP、Java五种语言的直播推流RTMP协议技术实施方案和思路-优雅草卓伊凡
Go、Node.js、Python、PHP、Java五种语言的直播推流RTMP协议技术实施方案和思路-优雅草卓伊凡
709 0