Spring Boot 使用多级缓存 {Caffeine+Redis}
快速入门 粘贴即用
maven依赖
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.5.5</version>
</dependency>
配置
package com.example.springredisson;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.redisson.spring.data.connection.RedissonConnectionFactory;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
/**
* @author bsg
* @date 2021/11/6
* @description 本地缓存 配置caffeine
*/
@Configuration
public class CacheConfig {
/**
* 配置缓存管理器
* Primary 优先加载
* @return 缓存管理器
*/
@Bean("caffeineCacheManager")
@Primary
public CacheManager cacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
cacheManager.setCaffeine(Caffeine.newBuilder()
// 设置最后一次写入或访问后经过固定时间过期
.expireAfterAccess(20, TimeUnit.SECONDS)
// 初始的缓存空间大小
.initialCapacity(100)
// 缓存的最大条数
.maximumSize(1000));
return cacheManager;
}
/**
* 这里使用了redisson
* spring-redis 换成 RedisConnectionFactory
* @param redisConnectionFactory
* @return
*/
@Bean("redisCacheManager")
public CacheManager redisCacheManager(RedissonConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(4))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
.cacheDefaults(redisCacheConfiguration).build();
}
}
启动类 @EnableCaching 这个注解是开启本地缓存(cache)的
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
-
@author bsg
-
@date 2021/11/6
-
@description
*/
@SpringBootApplication
@EnableCaching // 开启本地缓存
@EnableAspectJAutoProxy // aop
public class SpringRedissonApplication {public static void main(String[] args) {
SpringApplication.run(SpringRedissonApplication.class, args);
}
}
实体类
package com.example.springredisson;
import lombok.Data;
/**
* @Author: bsg
* @Date 2021/11/9 17:58
* @Version 1.0
* @description TODO
*/
@Data
public class User {
private int id;
private String name;
private String remark;
}
测试类 带有 @CacheLevel 这个注解的 是我自己实现的切面注解
package com.example.springredisson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author bsg
* @date 2021/11/6
* @description 自定义缓存 aop
*/
@RestController
public class test {
private static Logger logger = LoggerFactory.getLogger(test.class);
/**
* 本地缓存 测试 咖啡因
* @return
*/
@GetMapping("/test1")
@Cacheable(value = "caffeine")
public String test(User user) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "本地缓存测试";
}
/**
* 远程缓存测试 redis
* @return
*/
@GetMapping("/test2")
@Cacheable(value = "redis",cacheManager = "redisCacheManager")
public String test2(User user) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "远程缓存测试缓存测试";
}
/**
* 二级缓存 咖啡因 +redis 指定id
* @param user
* @return
*/
@GetMapping("/test3")
@CacheLevel(value = "cacheLevel",id ="#user.id")
public User test3(User user) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
user.setRemark("二级缓存测试 指定id");
return user;
}
/**
* 删除二级缓存 指定id
* @param user
* @return
*/
@GetMapping("/test4")
@CacheLevel(value = "cacheLevel",id ="#user.id",type =CacheLevelEnum.DELETE)
public String test4(User user) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "删除成功";
}
/**
* 二级缓存 咖啡因 +redis 未指定id
* @param user
* @return
*/
@GetMapping("/test5")
@CacheLevel(value = "cacheLevel")
public User test5(User user) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
user.setRemark("二级缓存测试 不指定id");
return user;
}
/**
* 删除二级缓存 未指定id
* @param user
* @return
*/
@GetMapping("/test6")
@CacheLevel(value = "cacheLevel",type = CacheLevelEnum.DELETE)
public String test6(User user) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
user.setRemark("二级缓存测试 不指定id");
return "删除成功";
}
}