Springboot集成Ehcache3实现本地缓存

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

1、引入相关依赖

java 复制代码
		<!-- 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配置

java 复制代码
spring:
  cache:
    type: jcache
    jcache:
      config: classpath:cache/ehcache.xml

3、配置ehcache.xml文件

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、编写缓存策略枚举

java 复制代码
public enum CacheStrategy {
    EXPIRE_30_MINUTES,
    EXPIRE_24_HOURS,
    EXPIRE_NONE
}

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

java 复制代码
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进行简单测试

java 复制代码
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、分别调用接口查看日志打印

相关推荐
茶卡盐佑星_44 分钟前
强缓存和协商缓存的区别
缓存
潘多编程1 小时前
Spring Boot微服务架构设计与实战
spring boot·后端·微服务
2402_857589361 小时前
新闻推荐系统:Spring Boot框架详解
java·spring boot·后端
原机小子1 小时前
Spring Boot框架下的新闻推荐技术
服务器·spring boot·php
2401_857622662 小时前
新闻推荐系统:Spring Boot的可扩展性
java·spring boot·后端
北极无雪2 小时前
Spring源码学习(拓展篇):SpringMVC中的异常处理
java·开发语言·数据库·学习·spring·servlet
Amagi.3 小时前
Spring中Bean的作用域
java·后端·spring
2402_857589363 小时前
Spring Boot新闻推荐系统设计与实现
java·spring boot·后端
J老熊3 小时前
Spring Cloud Netflix Eureka 注册中心讲解和案例示范
java·后端·spring·spring cloud·面试·eureka·系统架构
CoderJia程序员甲4 小时前
重学SpringBoot3-集成Redis(四)之Redisson
java·spring boot·redis·缓存