1、引入maven
<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、配置类
package com.base.config;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.base.consts.Consts;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
@Configuration
@EnableCaching
public class CaffeineCacheConfig {
@Bean
public Caffeine caffeineConfig() {
return Caffeine.newBuilder()
.expireAfterWrite(5, TimeUnit.MINUTES)
.maximumSize(100);
}
@Bean
public CacheManager cacheManager(Caffeine caffeine) {
CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
caffeineCacheManager.setCaffeine(caffeine);
caffeineCacheManager.setCacheNames(Arrays.asList(Consts.FIRST_CACHE)); // 配置缓存名称
return caffeineCacheManager;
}
}
3、工具类
package com.base.utils;
import com.base.consts.Consts;
import com.base.exception.ServiceException;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Component;
@Component
public class CaffeineUtil {
private CacheManager cacheManager;
public CaffeineUtil(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
/**
* 添加该字段缓存
*/
public void addToCache(String key, Object value) {
addToCache(Consts.FIRST_CACHE, key, value);
}
private void addToCache(String cacheName, String key, Object value) {
Cache cache = cacheManager.getCache(cacheName);
if (cache != null) {
if (cache.get(key) != null) {
cache.evict(key); // 清除现有缓存
}
cache.put(key, value); // 添加新数据到缓存
} else {
throw new ServiceException("Cache '" + cacheName + "' not found");
}
}
/**
* 获取该字段缓存
*/
public <T> T getFromCache(String key) {
return getFromCache(Consts.FIRST_CACHE, key);
}
@SuppressWarnings("unchecked")
private <T> T getFromCache(String cacheName, String key) {
Cache cache = cacheManager.getCache(cacheName);
if (cache != null) {
Cache.ValueWrapper valueWrapper = cache.get(key);
if (valueWrapper != null) {
return (T) valueWrapper.get();
}
}
return null;
}
/**
* 删除该字段缓存
*/
public void deleteFromCache( String key) {
deleteFromCache(Consts.FIRST_CACHE, key);
}
private void deleteFromCache(String cacheName, String key) {
Cache cache = cacheManager.getCache(cacheName);
if (cache != null) {
if (cache.get(key) != null) {
cache.evict(key); // 清除现有缓存
}
} else {
throw new ServiceException("Cache '" + cacheName + "' not found");
}
}
}
4、基本使用
public class test{
@Autowired
CaffeineUtil caffeineUtil;
public void testCaffeine() {
caffeineUtil.addToCache("key","value");
String testConfig = caffeineUtil.getFromCache(key);
if (null == testConfig) {
System.out.println("Cache not found");
}else{
System.out.println("Cache found");
}
}
5、Spring Boot应用的主类或者配置类上添加@EnableCaching
注解来启用缓存功能,
在需要使用缓存的方法上添加@Cacheable
注解。
import org.springframework.cache.annotation.Cacheable;
public class UserService {
@Cacheable("users")
public User findUserById(String userId) {
// 这里是获取用户信息的逻辑
}
}
6、注解
主要基于Spring缓存注解@Cacheable、@CacheEvict、@CachePut的方式使用。
@Cacheable :改注解修饰的方法,若不存在缓存,则执行方法并将结果写入缓存;若存在缓存,则不执行方法,直接返回缓存结果。
@CachePut :执行方法,更新缓存;该注解下的方法始终会被执行。
@CacheEvict :删除缓存
@Caching 将多个缓存组合在一个方法上(该注解可以允许一个方法同时设置多个注解)
@CacheConfig 在类级别设置一些缓存相关的共同配置(与其它缓存配合使用)
注意 :@Cacheable 默认使用标@primary 注释的CacheManage
/**
* 先查缓存,如果查不到,执行方法体并将结果写入缓存,若查到,不执行方法体,直接返回缓存结果
* @param id
*/
@Cacheable(value = "name1", key = "#id", sync = true)
public void getUser(long id){
//TODO 查找数据库
}
/**
* 更新缓存,每次都会执行方法体
* @param user
*/
@CachePut(value = "name1", key = "#user.id")
public void saveUser(User user){
//todo 保存数据库
}
/**
* 删除
* @param user
*/
@CacheEvict(value = "name1",key = "#user.id")
public void delUser(User user){
//todo 保存数据库
}