Spring Boot 本地缓存工具类设计与实现

在 Spring Boot 应用中,缓存是提升性能的重要手段之一。为了更方便地使用缓存,我们可以设计一套通用的本地缓存工具类,封装常见的缓存操作,简化开发流程。本文将详细介绍如何设计并实现一套 Spring Boot 本地缓存工具类,并提供完整代码示例。


1. 工具类设计目标

在设计缓存工具类时,我们需要考虑以下目标:

  1. 通用性:工具类应支持多种缓存操作,如获取、添加、更新、删除等。
  2. 易用性:通过简单的 API 调用即可完成缓存操作,减少重复代码。
  3. 灵活性:支持自定义缓存过期时间、缓存键生成策略等。
  4. 可扩展性:工具类应易于扩展,支持不同的缓存实现(如 Caffeine、Guava 等)。

2. 工具类实现

2.1 添加依赖

首先,在 pom.xml 中添加 Spring Boot 缓存支持的依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
</dependency>

2.2 启用缓存

在 Spring Boot 启动类上添加 @EnableCaching 注解,启用缓存功能:

java 复制代码
@SpringBootApplication
@EnableCaching
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

2.3 缓存工具类实现

以下是一个通用的本地缓存工具类实现,基于 Spring 的 CacheManager 和 Caffeine 缓存库:

java 复制代码
package com.example.cache;

import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.concurrent.Callable;

/**
 * 本地缓存工具类
 */
@Component
public class LocalCacheUtil {

    @Resource
    private CacheManager cacheManager;

    /**
     * 获取缓存值
     *
     * @param cacheName 缓存名称
     * @param key       缓存键
     * @return 缓存值
     */
    public <T> T get(String cacheName, Object key) {
        Cache cache = getCache(cacheName);
        if (cache != null) {
            Cache.ValueWrapper valueWrapper = cache.get(key);
            if (valueWrapper != null) {
                return (T) valueWrapper.get();
            }
        }
        return null;
    }

    /**
     * 获取缓存值,如果不存在则通过 loader 加载
     *
     * @param cacheName 缓存名称
     * @param key       缓存键
     * @param loader    缓存加载器
     * @return 缓存值
     */
    public <T> T get(String cacheName, Object key, Callable<T> loader) {
        Cache cache = getCache(cacheName);
        if (cache != null) {
            return cache.get(key, loader);
        }
        return null;
    }

    /**
     * 添加缓存
     *
     * @param cacheName 缓存名称
     * @param key       缓存键
     * @param value     缓存值
     */
    public void put(String cacheName, Object key, Object value) {
        Cache cache = getCache(cacheName);
        if (cache != null) {
            cache.put(key, value);
        }
    }

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

    /**
     * 清空缓存
     *
     * @param cacheName 缓存名称
     */
    public void clear(String cacheName) {
        Cache cache = getCache(cacheName);
        if (cache != null) {
            cache.clear();
        }
    }

    /**
     * 获取缓存对象
     *
     * @param cacheName 缓存名称
     * @return 缓存对象
     */
    private Cache getCache(String cacheName) {
        if (!StringUtils.hasText(cacheName)) {
            throw new IllegalArgumentException("缓存名称不能为空");
        }
        return cacheManager.getCache(cacheName);
    }
}

3. 工具类使用示例

3.1 配置缓存

application.yml 中配置 Caffeine 缓存:

yaml 复制代码
spring:
  cache:
    type: caffeine
    caffeine:
      spec: maximumSize=1000,expireAfterWrite=10m

3.2 使用工具类

在业务代码中,可以通过注入 LocalCacheUtil 来使用缓存工具类:

java 复制代码
@Service
public class BookService {

    @Resource
    private LocalCacheUtil localCacheUtil;

    /**
     * 获取书籍信息
     */
    public Book getBookById(Long id) {
        // 先从缓存中获取
        Book book = localCacheUtil.get("books", id);
        if (book == null) {
            // 如果缓存中不存在,则从数据库加载
            book = loadBookFromDatabase(id);
            // 将结果放入缓存
            localCacheUtil.put("books", id, book);
        }
        return book;
    }

    /**
     * 更新书籍信息
     */
    public void updateBook(Book book) {
        // 更新数据库
        updateBookInDatabase(book);
        // 更新缓存
        localCacheUtil.put("books", book.getId(), book);
    }

    /**
     * 删除书籍信息
     */
    public void deleteBookById(Long id) {
        // 删除数据库记录
        deleteBookFromDatabase(id);
        // 删除缓存
        localCacheUtil.evict("books", id);
    }

    // 模拟从数据库加载书籍信息
    private Book loadBookFromDatabase(Long id) {
        // 这里模拟数据库查询
        return new Book(id, "Spring Boot Guide", "Author Name");
    }

    // 模拟更新数据库
    private void updateBookInDatabase(Book book) {
        // 这里模拟数据库更新
    }

    // 模拟删除数据库记录
    private void deleteBookFromDatabase(Long id) {
        // 这里模拟数据库删除
    }
}

4. 工具类的优势

  1. 简化缓存操作:通过工具类封装,业务代码中只需调用简单的方法即可完成缓存操作。
  2. 统一管理缓存:所有缓存操作都通过工具类进行,便于维护和扩展。
  3. 支持多种缓存策略:可以通过配置灵活调整缓存过期时间、最大容量等参数。
  4. 易于扩展:如果需要切换缓存实现(如从 Caffeine 切换到 Ehcache),只需修改配置,无需改动业务代码。

5. 总结

本文设计并实现了一套 Spring Boot 本地缓存工具类,通过封装 Spring 的 CacheManager 和 Caffeine 缓存库,提供了简单易用的缓存操作 API。该工具类可以显著简化缓存的使用,提升开发效率,同时具备良好的扩展性和灵活性。希望本文能帮助你更好地理解和使用 Spring Boot 中的本地缓存功能。

如果你有任何问题或建议,欢迎在评论区留言讨论!

相关推荐
uhakadotcom26 分钟前
Pandas入门:数据处理和分析的强大工具
后端·面试·github
Asthenia041228 分钟前
Json里面想传图片(验证码图)-Base64编码来助你!
后端
亭墨1 小时前
linux0.11内核源码修仙传第五章——内存初始化(主存与缓存)
linux·c语言·驱动开发·学习·缓存·系统架构
服务端技术栈1 小时前
MySQL 索引:数据库查询的“加速器”
后端
Asthenia04121 小时前
Redis与MySQL协同:旁路缓存机制
后端
hamburgerDaddy11 小时前
golang 从零单排 (一) 安装环境
开发语言·后端·golang
Asthenia04121 小时前
线程的生命周期状态你烂熟于心,那线程池呢?Running/ShutDown/Stop/Tidying/Terminated
后端
小画家~1 小时前
第本章:go 切片
开发语言·后端·golang
小画家~1 小时前
第五章:go 的数据类型 及go语言拼接字符串有哪些方式
开发语言·后端·golang
小华同学ai2 小时前
2K star!三分钟搭建企业级后台系统,这款开源Java框架绝了!
后端·架构·github