在 Spring Boot 应用中,缓存是提升性能的重要手段之一。为了更方便地使用缓存,我们可以设计一套通用的本地缓存工具类,封装常见的缓存操作,简化开发流程。本文将详细介绍如何设计并实现一套 Spring Boot 本地缓存工具类,并提供完整代码示例。
1. 工具类设计目标
在设计缓存工具类时,我们需要考虑以下目标:
- 通用性:工具类应支持多种缓存操作,如获取、添加、更新、删除等。
- 易用性:通过简单的 API 调用即可完成缓存操作,减少重复代码。
- 灵活性:支持自定义缓存过期时间、缓存键生成策略等。
- 可扩展性:工具类应易于扩展,支持不同的缓存实现(如 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. 工具类的优势
- 简化缓存操作:通过工具类封装,业务代码中只需调用简单的方法即可完成缓存操作。
- 统一管理缓存:所有缓存操作都通过工具类进行,便于维护和扩展。
- 支持多种缓存策略:可以通过配置灵活调整缓存过期时间、最大容量等参数。
- 易于扩展:如果需要切换缓存实现(如从 Caffeine 切换到 Ehcache),只需修改配置,无需改动业务代码。
5. 总结
本文设计并实现了一套 Spring Boot 本地缓存工具类,通过封装 Spring 的 CacheManager
和 Caffeine 缓存库,提供了简单易用的缓存操作 API。该工具类可以显著简化缓存的使用,提升开发效率,同时具备良好的扩展性和灵活性。希望本文能帮助你更好地理解和使用 Spring Boot 中的本地缓存功能。
如果你有任何问题或建议,欢迎在评论区留言讨论!