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实现方案
相关文章:
Java Cache 缓存方案详解及代码-Ehcache
一、Spring缓存概念 Spring从3.1开始定义了 org.springframework.cache.Cache 和 org.springframework.cache.CacheManager 接口来统一不同的缓存技术; 并支持使用 JCache(JSR-107) 注解简化我们开发。 常用的缓存实现有 RedisCache 、EhCach…...

JAVA设计模式-装饰者模式
一.概念 装饰器模式(Decorator Pattern),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更灵活。 —-《大话设计模式》 允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属…...

STM32F1简介
前言 本次学习使用的是STM32F1系列的芯片,72MHz的Cortex-M3内核; 名词解释 STM32是ST公司基于ARM Cortex-M内核开发的32位微控制器(MCU); ARM Cortex-M内核是ARM公司设计的,程序指令的执行,…...

SpringBoot面试题6:Spring Boot 2.X 有什么新特性?与 1.X 有什么区别?
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:Spring Boot 2.X 有什么新特性?与 1.X 有什么区别? Spring Boot是一种用于简化Spring应用程序开发的框架,它提供了自动配置、起步依赖和快速开…...

qt笔记之qml下拉标签组合框增加发送按钮发送标签内容
qt笔记之qml下拉标签组合框增加发送按钮发送标签内容 code review! 文章目录 qt笔记之qml下拉标签组合框增加发送按钮发送标签内容1.运行2.文件结构3.main.qml4.main.cc5.MyClass.h6.MyClass.cc7.CMakeLists.txt8.ComboBox.pro9.qml.qrc 1.运行 2.文件结构 3.main.qml 代码 …...
linux上构建任意版本的rocketmq多架构x86 arm镜像——筑梦之路
现状 目前市面上和官方均只有rocketmq x86架构下的docker镜像,而随着国产化和信创适配的需求越来越多,显然现有的x86架构下的docker镜像不能满足多样化的需求,因此我们需要根据官方发布的版本制作满足需求的多架构镜像,以在不同cp…...
Java8 新特性之Stream(五)-- Stream的3种创建方法
目录 1. 集合 创建Stream流 拓展: 2. 数组 创建Stream流 3. 静态方法 创建Stream流 1. 集合 创建Stream流 @...
Vue实现模糊查询搜索功能
第一步 先创建一个val变量 // 用户搜索内容 let val ref(""); 第二步:给input绑定v-model (为了获取input框的值) <input v-model"val" type"text" placeholder"请输入行业/公司/名称"/> 第…...

(C++ STL) 详解vector模拟实现
目录 一.vector的介绍 1.vector的介绍 二.vector的定义模拟实现 三.vector各接口的模拟实现 1.vector迭代器的模拟实现 2.构造函数 2.1无参构造 2.2 n个val构造 2.3迭代器区间构造 2.4通过对象初始化(拷贝构造) 3.析构函数 4.size 5.operato…...

c语言从入门到实战——C语言数据类型和变量
C语言数据类型和变量 前言1. 数据类型介绍1.1 字符型1.2 整型1.3 浮点型1.4 布尔类型1.5 各种数据类型的长度1.5.1 sizeof操作符1.5.2 数据类型长度1.5.3 sizeof中表达式不计算 2. signed 和 unsigned3. 数据类型的取值范围4. 变量4.1 变量的创建4.2 变量的分类 5. 算术操作符&…...

[论文精读]Semi-Supervised Classification with Graph Convolutional Networks
论文原文:[1609.02907] Semi-Supervised Classification with Graph Convolutional Networks (arxiv.org) 论文代码:GitHub - tkipf/gcn: Implementation of Graph Convolutional Networks in TensorFlow 英文是纯手打的!论文原文的summari…...
CICD:使用docker+ jenkins + gitlab搭建cicd服务
持续集成解决什么问题 提高软件质量效率迭代便捷部署快速交付、便于管理 持续集成(CI) 集成,就是一些孤立的事物或元素通过某种方式集中在一起,产生联系,从而构建一个有机整体的过程。 持续,就是指长期…...

新能源电池试验中准确模拟高空环境大气压力的解决方案
摘要:针对目前新能源电池热失控和特性研究以及生产中缺乏变环境压力准确模拟装置、错误控制方法造成环境压力控制极不稳定以及氢燃料电池中氢气所带来的易燃易爆问题,本文提出了相应的解决方案。方案的关键一是采用了低漏率电控针阀作为下游控制调节阀实…...
Python 中的模糊字符串匹配
文章目录 Python中使用thefuzz模块匹配模糊字符串使用process模块高效地使用模糊字符串匹配今天,我们将学习如何使用 thefuzz 库,它允许我们在 python 中进行模糊字符串匹配。 此外,我们将学习如何使用 process 模块,该模块允许我们借助模糊字符串逻辑有效地匹配或提取字符…...
记录一个奇怪bug
一开始Weapon脚本是继承Monobehavior的,实例化后挂在gameObject上跟着角色。后来改成了不继承mono的,也不实例化。过程都是顺利的,运行也没问题,脚本编辑器也没有错误。 但偶尔有一次报了一些错误,大概是说Weapon (1)…...

SpringBoot面试题7:SpringBoot支持什么前端模板?
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:SpringBoot支持什么前端模板? Spring Boot支持多种前端模板,其中包括以下几种常用的: Thymeleaf:Thymeleaf是一种服务器端Java模板引擎,能够…...
leetcode做题笔记172. 阶乘后的零
给定一个整数 n ,返回 n! 结果中尾随零的数量。 提示 n! n * (n - 1) * (n - 2) * ... * 3 * 2 * 1 示例 1: 输入:n 3 输出:0 解释:3! 6 ,不含尾随 0示例 2: 输入:n 5 输出&a…...
linux之shell脚本练习
以下脚本已经是在ubuntu下测试的 demo持续更新中。。。 1、for 循环测试,,,Ping 局域网 #!/bin/bashi1 for i in {1..254} do# 每隔0.3s Ping 一次,每次超时时间3s,Ping的结果直接废弃ping-w 3 -i 0.3 192.168.110.$i…...

CSS阶详细解析一
CSS进阶 目标:掌握复合选择器作用和写法;使用background属性添加背景效果 01-复合选择器 定义:由两个或多个基础选择器,通过不同的方式组合而成。 作用:更准确、更高效的选择目标元素(标签)。…...

osWorkflow-1——osWorkflow官方例子部署启动运行(版本:OSWorkflow-2.8.0)
osWorkflow-1——osWorkflow官方例子部署启动运行(版本:OSWorkflow-2.8.0) 1. 前言——准备工作1.1 下载相关资料1.2 安装翻译插件 2. 开始搞项目2.1 解压 .zip文件2.2 简单小测(war包放入tomcat)2.3 导入项目到 IDE、…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...