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

一、Spring缓存概念

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

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

1、Spring Cache 介绍

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

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

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

CacheManager

描述

EhCacheCacheManager

使用EhCache作为缓存技术

GuavaCacheManager

使用Google的GuavaCache作为缓存技术

RedisCacheManager

使用Redis作为缓存技术

2、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*/@Beanpublic EhCacheCacheManager ehCacheCacheManager(EhCacheManagerFactoryBean ehCacheManagerFactoryBean){System.out.println("CacheConfiguration.ehCacheCacheManager()");return new EhCacheCacheManager(ehCacheManagerFactoryBean.getObject());}/** 据shared与否的设置,* Spring分别通过CacheManager.create()* 或new CacheManager()方式来创建一个ehcache基地.*/@Beanpublic 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实现方案

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/110222.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【达梦数据库】mysql函数改写达梦

yearweek 改写为 year(‘2019-07-11’)||WEEK(‘2019-07-11’,1); mysql> select YEARWEEK(2019-07-11,1); -------------------------- | YEARWEEK(2019-07-11,1) | -------------------------- | 201928 | -------------------------- 1 row in set (0…

解决GET请求入参@NotNull验证不生效问题

一、问题 get请求NotNull验证不生效 二、解决方案 两个步骤&#xff1a; 在该方法的controller类上加Validated&#xff1b;在参数面前加NotNull&#xff1b; 三、其他注解 //被注释的元素必须为null Null //被注释的元素不能为null NotNull //被注释的元素必须为true Ass…

[一带一路金砖 2023 CTF]Crypto

题1 题目描述&#xff1a; from Crypto.Util.number import * from flag import flag import gmpy2 assert(len(flag)38) flag bytes_to_long(flag)p getPrime(512) q getPrime(512)e 304 enc pow(flag,e,p*q) print(p) print(q) print(enc) #9794998439882070838464987…

CSS盒子模型的详细解析

03-盒子模型 作用&#xff1a;布局网页&#xff0c;摆放盒子和内容。 盒子模型-组成 内容区域 – width & height 内边距 – padding&#xff08;出现在内容与盒子边缘之间&#xff09; 边框线 – border 外边距 – margin&#xff08;出现在盒子外面&#xff09; d…

赎金信(C++解法)

题目 给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以&#xff0c;返回 true &#xff1b;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 示例 1&#xff1a; 输入…

【Git】bad signature 0x00000000 index file corrupt. fatal: index file corrupt

问题描述 电脑写代码时蓝屏。重启后 git commit 出错。 error: bad signature 0x00000000 fatal: index file corrupt原因分析 当电脑发生蓝屏或异常关机时&#xff0c;Git 的索引文件可能损坏。 解决方案 删除损坏的索引文件。 rm -Force .git/index回退到上一个可用的版…

第十九章 文件操作

程序运行时产生的数据都属于临时数据&#xff0c;程序一旦运行结束都会被释放 通过文件可以将数据持久化 C中对文件操作需要包含头文件 < fstream > 文件类型分为两种&#xff1a; 文本文件 - 文件以文本的ASCII码形式存储在计算机中 二进制文件 - 文件以文本的二进制…

C语言 内存

内存分配 内存分配的类型 C/C中内存分为5个区&#xff0c;分别为栈区、堆区、全局/静态存储区、常量存储区、代码区 静态内存分配&#xff1a;编译时分配&#xff0c;包括全局、静态全局、静态局部三种变量。 动态内存分配&#xff1a;运行时分配&#xff0c;包括栈&#x…

图论相关算法

一、迪杰斯特拉(Dijkstra)算法 迪杰斯特拉算法使用类似广度优先搜索的方法解决了带权图的单源最短路径问题。这是一个贪心算法。 1.核心思想 &#xff08;1&#xff09;每次选中一个点&#xff0c;这个点满足两个条件&#xff1a; 未被选过距离最短 &#xff08;2&#xf…

一些前端面试思考

回流和重绘 先牢记这句话&#xff0c;回流必将引起重绘&#xff0c;而重绘不一定会引起回流。回流的代价要远大于重绘。 当你给一个元素更换颜色&#xff0c;这样的行为是不会影响页面布局的&#xff0c;DOM树不会变化&#xff0c;但颜色变了&#xff0c;渲染树得重新渲染页面&…

Linux系统管理:虚拟机OpenEuler安装

目录 一、理论 1.OpenEuler 二、实验 1.虚拟机OpenEuler安装准备阶段 2.安装OpenEuler 3.进入系统 一、理论 1.OpenEuler &#xff08;1&#xff09;简介 欧拉&#xff08;Euler&#xff09;是数字基础设施的开源操作系统&#xff0c;可广泛部署于服务器、云计算、边缘…

LeetCode75——Day9

文章目录 一、题目二、题解 一、题目 443. String Compression Given an array of characters chars, compress it using the following algorithm: Begin with an empty string s. For each group of consecutive repeating characters in chars: If the group’s length …

如何利用PHP快速抓取音频数据?

以下是一个使用Dusk库和PHP编写的爬虫程序&#xff0c;用于爬取海量的音频数据。这个程序使用了https://www.duoip.cn/get_proxy的代码。 <?php // 引入Dusk库 require Dusk.php;// 创建Dusk对象 $dusk new Dusk();// 设置代理 $dusk->setProxy(127.0.0.1, 8080);// 使…

Unity2023, Unity2022, Unity2021的性能对比(帧率)

最近由于需要用到Unity最新版的一些功能&#xff0c;比如Spline&#xff0c;比如Foward渲染&#xff0c;新项目用了Unity2022.3.5版本&#xff0c;但是出包之后&#xff0c;感觉帧率很低。本着好奇的态度&#xff0c;专门写了一个测试场景&#xff0c;分别在Unity2023.1.15&…

PostgreSQL数据库配置文件

PostgreSQL数据库配置文件 配置文件postgresql.conf数据库连接认证参数数据库内存参数WAL日志参数错误日志参数 配置文件pg_hba.conf PostgreSQL版本&#xff1a;10.5 检查数据库参数&#xff1a; postgres# select name,setting,unit from pg_settings where name in (max_…

vue3+koa+axios实现前后端通信

vue3koaaxios实现前后端通信 写了一个小demo来实现前后端通信,涉及跨域问题&#xff0c;非常简单可以给大家平时开发的时候参考 服务端&#xff1a; 目录结构如下&#xff1a; router index.js // router的入口文件 // 引入路由 const Router require("koa-router&quo…

记一次mysql事务并发优化

记一次mysql事务并发优化 背景 事情的情况大致是这样的。一个扣减库存的业务上线以后&#xff0c;隔几天会报一次错&#xff0c;错误内容如下&#xff1a; ERROR - exception: UncategorizedSQLException,"detail":"org.springframework.jdbc.UncategorizedSQ…

[蓝桥杯 2022 省 B] 统计子矩阵

题目描述 给定一个 NM 的矩阵 A&#xff0c;请你统计有多少个子矩阵 (最小 11, 最大 NM) 满足子矩阵中所有数的和不超过给定的整数 K。 输入格式 第一行包含三个整数 N, M和 K。 之后 N 行每行包含 M 个整数, 代表矩阵 A。 输出格式 一个整数代表答案。 输入输出样例 输入 #1 3…

Spring framework Day22:Aware接口

前言 在Spring框架中&#xff0c;有许多接口和类都有一个非常重要的作用——让我们能够更方便地构建应用程序和管理组件。其中&#xff0c;Aware接口就是其中一个非常重要的接口之一。通过实现该接口&#xff0c;我们可以让Spring容器感知到特定的组件和资源&#xff0c;并进行…

讲解 CSS 过渡和动画 — transition/animation (很全面)

前言 由于用户越来越注重 Web应用 的使用体验&#xff0c;随之而来的是 Web应用 需要提供了更加完善的 Web 动画 效果来实现以平滑的状态贯穿于用户的整个使用过程中。现在&#xff0c;这已经是司空见惯了&#xff0c;用户潜意识是希望可以获得更快的反馈响应和更友好的用户界…