Springboot集成Ehcache3实现本地缓存

如果只需要在单个应用程序中使用本地缓存,则可以选择Ehcache;它支持内存和磁盘存储,这里不以注解方式演示,通过自己实现缓存管理者灵活控制缓存的读写;

1、引入相关依赖

		<!-- ehcache3集成start -->
		<dependency>
			<groupId>org.ehcache</groupId>
			<artifactId>ehcache</artifactId>
			<version>3.10.8</version>
		</dependency>
		<dependency>
			<groupId>javax.cache</groupId>
			<artifactId>cache-api</artifactId>
		</dependency>
		<!-- ehcache3集成end -->

2、修改yml配置

spring:
  cache:
    type: jcache
    jcache:
      config: classpath:cache/ehcache.xml

3、配置ehcache.xml文件

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.ehcache.org/v3"
        xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd">
    <!-- 缓存持久化配置: 定义磁盘缓存位置 -->
    <persistence directory="E:/project_home/limit_control/cache/light-element-mybatis"/>
    <!-- 缓存模板: 未填写缓存名时使用的默认缓存,同时也可被继承 -->
    <cache-template name="defaultCache">
        <key-type>java.lang.String</key-type>
        <value-type>java.lang.Object</value-type>
        <resources>
            <heap unit="MB">64</heap>
            <offheap unit="MB">128</offheap>
        </resources>
    </cache-template>
    <!-- 缓存列表: 自定义缓存配置 -->
    <!-- 不过期 -->
    <cache alias="EXPIRE_NONE" uses-template="defaultCache"/>
    <!-- 24小时过期 -->
    <cache alias="EXPIRE_24_HOURS" uses-template="defaultCache">
        <expiry>
            <ttl unit="hours">24</ttl>
        </expiry>
    </cache>
    <!-- 30分钟过期 -->
    <cache alias="EXPIRE_30_MINUTES" uses-template="defaultCache">
        <expiry>
            <ttl unit="minutes">30</ttl>
        </expiry>
    </cache>
</config>

4、编写缓存策略枚举

public enum CacheStrategy {
    EXPIRE_30_MINUTES,
    EXPIRE_24_HOURS,
    EXPIRE_NONE
}

5、编写缓存管理者,来控制缓存的增删改查

import com.alibaba.fastjson.JSON;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;

import java.util.List;

/**
 * ehcache3缓存管理者
 */
@Configuration
@EnableCaching
public class EhCacheManager {
    private static CacheManager cacheManager;

    public EhCacheManager(CacheManager cacheManager) {
        EhCacheManager.cacheManager = cacheManager;
    }

    /**
     * 获取默认缓存
     *
     * @return
     */
    public static Cache getDefaultCache() {
        return getCache("EXPIRE_24_HOURS");
    }

    /**
     * 获取指定缓存
     *
     * @param cacheName 缓存名称
     * @return
     */
    public static Cache getCache(String cacheName) {
        if (cacheManager == null) {
            return null;
        }
        return cacheManager.getCache(cacheName);
    }

    /**
     * 获取缓存内容(对象)
     *
     * @param cacheName 缓存名称
     * @param key       键
     * @param clazz<T>  class类型
     * @return
     */
    public static <T extends Object> T getObjValue(String cacheName, String key, Class<T> clazz) {
        Object o = getValue(cacheName, key);
        if (o == null) {
            return null;
        }
        T t = (T) JSON.parseObject(JSON.toJSONString(o), clazz);
        return t;
    }

    /**
     * 获取缓存内容(集合)
     *
     * @param cacheName 缓存名称
     * @param key       键
     * @param clazz<T>  class类型
     * @return
     */
    public static <T extends Object> List<T> getListValue(String cacheName, String key, Class<T> clazz) {
        Object o = getValue(cacheName, key);
        if (o == null) {
            return null;
        }
        List<T> ts = JSON.parseArray(JSON.toJSONString(o), clazz);
        return ts;
    }

    /**
     * 获取缓存内容
     *
     * @param cacheName
     * @param key
     * @return
     */
    private static Object getValue(String cacheName, String key) {
        Cache cache = getCache(cacheName);
        if (cache == null && cache.get(key) == null) {
            return null;
        }
        Cache.ValueWrapper valueWrapper = cache.get(key);
        if (valueWrapper == null) {
            return null;
        }
        Object o = valueWrapper.get();
        if (o == null) {
            return null;
        }
        return o;
    }

    /**
     * 新增或修改缓存数据
     *
     * @param cacheName 缓存名称
     * @param key       键
     * @param value     值
     */
    public static void put(String cacheName, String key, Object value) {
        Cache cache = getCache(cacheName);
        if (cache == null) {
            return;
        }
        cache.put(key, value);
    }

    /**
     * 删除缓存数据
     *
     * @param cacheName 缓存名称
     * @param key       键
     */
    public static void del(String cacheName, String key) {
        Cache cache = getCache(cacheName);
        if (cache == null) {
            return;
        }
        cache.evict(key);
    }
}

6、编写controller进行简单测试

import cn.hutool.core.collection.CollectionUtil;
import com.yx.light.element.mybatis.cache.CacheStrategy;
import com.yx.light.element.mybatis.cache.EhCacheManager;
import com.yx.light.element.mybatis.mapper.entity.GroupHeader;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping(value = "/index")
@Slf4j
public class IndexController {

    @GetMapping(value = "/list")
    public List<GroupHeader> list() {
        List<GroupHeader> listValue = EhCacheManager.getListValue(CacheStrategy.EXPIRE_30_MINUTES.name(), "list", GroupHeader.class);
        if (CollectionUtil.isEmpty(listValue)) {
            log.info("集合缓存不存在或已过期,查询数据库!");
            //模拟查库
            List<GroupHeader> objects = new ArrayList<>();
            for (int i = 0; i < 5; i++) {
                GroupHeader groupHeader = new GroupHeader();
                groupHeader.setGroupCode("aaaaa-" + i);
                groupHeader.setGroupName("多个对象" + i);
                objects.add(groupHeader);
            }
            listValue = objects;
            EhCacheManager.put(CacheStrategy.EXPIRE_30_MINUTES.name(), "list", listValue);
            log.info("集合数据加载到缓存!");
        } else {
            log.info("从集合缓存中直接获取数据!");
        }
        return listValue;
    }

    @GetMapping(value = "/one")
    public GroupHeader one() {
        GroupHeader objValue = EhCacheManager.getObjValue(CacheStrategy.EXPIRE_30_MINUTES.name(), "obj", GroupHeader.class);
        if (objValue == null) {
            log.info("对象缓存不存在或已过期,查询数据库!");
            //模拟查库
            GroupHeader groupHeader = new GroupHeader();
            groupHeader.setGroupCode("aaaaa");
            groupHeader.setGroupName("单个对象");
            objValue = groupHeader;
            EhCacheManager.put(CacheStrategy.EXPIRE_30_MINUTES.name(), "obj", groupHeader);
            log.info("对象数据加载到缓存!");
        } else {
            log.info("从对象缓存中直接获取数据!");
        }
        return objValue;
    }

    @GetMapping(value = "/del")
    public void del() {
        log.info("清理对象缓存!");
        EhCacheManager.del(CacheStrategy.EXPIRE_30_MINUTES.name(), "obj");
    }

}

7、分别调用接口查看日志打印

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ENSP-旁挂式AC

提醒&#xff1a;如果AC不能成功上线AP&#xff0c;一般问题不会出在AC上&#xff0c;优先关注AC-AP线路上的二层或三层组网的三层交换机 拓扑图 管理VLAN&#xff1a;99 | 业务VLAN&#xff1a;100 注意点&#xff1a; 1.连接AP的接口需要打上pvid为管理vlan的标签 2.AC和…

华为配置通过流策略实现流量统计

配置通过流策略实现流量统计示例 组网图形 图1 配置流策略实现流量统计组网图 设备 接口 接口所属VLAN 对应的三层接口 IP地址 SwitchA GigabitEthernet1/0/1 VLAN 10 - - GigabitEthernet1/0/2 VLAN 20 - - GigabitEthernet1/0/3 VLAN 10、VLAN 20 - - S…

【简单讲解下Stylus入门使用方法】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

树--平衡二叉树(AVL树)

平衡二叉树画图网站 一、有序二叉树可能存在的问题 给一个数列{1,2,3,4,5,6}&#xff0c;要求创建一颗二叉排序树&#xff08;BST&#xff09;并分析问题所在。 二、平衡二叉树的基本介绍 平衡二叉树具有以下特点&#xff1a; 它是一颗空树或它的左右两个子树的高度差的绝对…

【多线程】单例模式 | 饿汉模式 | 懒汉模式 | 指令重排序问题

文章目录 单例模式一、单例模式1.饿汉模式2.懒汉模式&#xff08;单线程&#xff09;3.懒汉模式&#xff08;多线程&#xff09;改进 4.指令重排序1.概念2.question:3.解决方法4总结&#xff1a; 单例模式 一、单例模式 单例&#xff0c;就是单个实例 在有些场景中&#xff0c…

艾体宝方案 | ITT-Profitap IOTA——铁路运输的远程网络捕获和故障排除方案

在移动互联时代&#xff0c;铁路运输的数字化转型已成不可逆转的趋势。然而&#xff0c;随之而来的是对网络连接质量和故障排查的更高要求。本文将探讨如何利用艾体宝Profitap IOTA技术&#xff0c;在火车上实现远程网络捕获和故障排查&#xff0c;助力铁路运输行业迈向智能化未…

✌粤嵌—2024/4/16—x的平方根

代码实现&#xff1a; int mySqrt(int x){if (x 0 || x 1) {return x;}long int i;for (i 1; i < x / 2; i) {if (i * i < x && (i 1) * (i 1) > x) {break;}}return i; }

关于小米消金-我以为的小米消金和实际的小米消金

我原以为的小米消金&#xff0c;是一个涵盖多种金融服务的平台&#xff0c;与小米品牌紧密相连&#xff0c;提供便捷的消费金融服务。然而&#xff0c;实际的小米消金&#xff0c;其业务范围、服务细节以及运营模式都与我之前的想象有所不同。它更注重用户体验&#xff0c;提供…

KVM虚拟机

文章目录 QEMU-KVM介绍虚拟网卡流程网卡透访流程 QEMU-KVM介绍 QEMU ● QEMU是一个主机上的VMM (Virtual machine monitor), 通过动态二进制模拟CPU&#xff0c;并提供一系列的硬件模型&#xff0c;使Guest OS能够与Host硬件交互。 ● QEMU的代码中有完整的虚拟机实现&#xf…

当路由模式为hash怎么对接京东物流回调链接

为什么我要写这篇文章呢&#xff1f;是因为最近在做这个需求&#xff0c;京东物流是需要自己手动点击授权后把返回的code拿去授权&#xff0c;刚开始以为一切都很顺利的&#xff0c;然而等我看到路由为hash时候&#xff0c;浏览器会忽略#后面的东西&#xff0c;所以是无法重新跳…

华三交换机知道ip怎么查找主机ip在接入交换机哪个端口下

环境&#xff1a; 华三S5120V3-52S-SI H3C Comware Software, Version 7.1.070, Release 6329 问题描述&#xff1a; 华三交换机知道ip怎么查找主机ip在接入交换机哪个端口下 已知主机ip192.168.1.111 解决方案&#xff1a; 在H3C&#xff08;新华三&#xff09;交换机上…

宝宝洗衣机买什么样的好?力荐四大表现突出婴儿洗衣机总汇

对于那些追求品质生活、分类洗涤的用户而言&#xff0c;专用的婴儿洗衣机可以满足我们对不同类型的宝宝衣物分开洗涤的需求&#xff0c;如果您家中有宝宝&#xff0c;或者您对个人卫生和健康有较高要求&#xff0c;这样的婴儿洗衣机可以提供高温洗涤程序&#xff0c;有效杀灭细…

单细胞核转录组——植物:叶叶我呀裂开啦~

单细胞转录组测序技术能够在单细胞分辨率下研究样本的转录组信息&#xff0c;可以完美解决细胞异质问题&#xff0c;能全面真实揭示细胞多样性和复杂性&#xff0c;能够更加深入地研究细胞类型、细胞功能、细胞亚群及其异质性、细胞谱系等&#xff0c;还常用于识别新的细胞类型…

【ARM 裸机】I.MX 启动方式之启动设备的选择

启动方式从两个方面来看&#xff0c;一是启动设备的选择&#xff0c;二是启动头文件的选择&#xff0c;本节是关于启动设备的选择&#xff1b; 1、硬件启动设备 回想一下上一节&#xff1a;【ARM 裸机】汇编 led 驱动之烧写 bin 文件&#xff0c;我们提到&#xff08;将 SD卡…

Springboot框架——3.整合SpringMVC

1.修改端口号&#xff1a; 在application.properties中添加如下配置即可&#xff1a; server.port8088 2.静态资源访问&#xff1a; 首先打开ResourceProperties这个类的源码&#xff1a; 将静态资源放到类中默认位置即可实现访问&#xff1a; http://localhost:8088/erth.jp…

bugku-web-xxx二手交易市场

这里直接来到一个交易平台 还是三板斧 源码查看 <script>$(#searchList li).click(function(){var type$(this).attr(aman-type);$(this).parent().find(li).attr(class,red);$(this).attr(class,red-on)search();});function search(){var url/index;var type$("#…

java通过maven导入本地jar包的三种方式

一、引入lib下加载&#xff08;加载过后打包&#xff0c;以后再次使用不用再次导入&#xff09; 首先创建一个用于创建jar包的项目&#xff0c;并测试能否成功运行 讲项目打包 在需要引入的项目中创建lib目录 并把刚才打包的jar复制进去 通过dependency引入jar包 groupId、art…

【安装部署】Apache SeaTunnel 和 Web快速安装详解

版本说明 由于作者目前接触当前最新版本为2.3.4 但是官方提供的web版本未1.0.0&#xff0c;不兼容2.3.4&#xff0c;因此这里仍然使用2.3.3版本。 可以自定义兼容处理&#xff0c;官方提供了文档&#xff1a;https://mp.weixin.qq.com/s/Al1VmBoOKu2P02sBOTB6DQ 因为大部分用…

详解数据中台,附案例

&#xff08;一&#xff09;什么是数据中台&#xff0c;有什么价值&#xff1f; 数据中台居于前台和后台之间&#xff0c;是企业级的数据共享、能力复用平台&#xff0c;是数字 化转型的基础和中枢系统。将企业全域海量、多源、异构的数据整合资产化&#xff0c;为业务前台提供…

使用TVM在树莓派部署yolov8模型(二)

这部分主要记录部署环境的搭建。 在电脑或服务器上编译&#xff0c;需要搭建完整的TVM工具链&#xff1b;树莓派上仅负责运行&#xff0c;因此只编译runtime即可。 先从简单的开始 一 在树莓派上编译runtime 我的树莓派是新装的系统&#xff0c;那就从头搭建环境吧。 我用的树…