基于注解方式缓存本地数据
一、简介
之前一直在忙,没有时间写一篇基于注解的缓存本地数据,因为有的小的业务没必要引入redis中间件,所以我个人觉得还是得根据自己的业务场景去使用。
二、实战代码
1.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.9.0</version>
</dependency>
2.springboot启动类需要启用注解
@SpringBootApplication
@EnableCaching //显式开启cache缓存
public class CacheApplication {
public static void main(String[] args) {
SpringApplication.run(CodeApplication.class, args);
}
}
3.自定义Cache注解
@AllArgsConstructor
@Getter
public enum CacheType {
/*
新增缓存方法步骤:
1. 在CacheType中新增缓存类型 (会自动创建缓存器) --> 也可以不定义新的缓存器 共用已经存在的缓存器 但要注意key的生成方式 避免key冲突
2. 在需要缓存的方法上加入 @Cacheable注解 并给@Cacheable注解 设置步骤1中的缓存名称 及 指定缓存key生成方式
缓存具体执行步骤:
1.会先根据key去缓存中找缓存
2.若找到缓存 则直接返回缓存中的数据 不会执行@Cacheable注解方法下的代码
若没有找到缓存 则会执行方法中的代码 然后将方法的返回结果进行缓存 key为@Cacheable注解中的key指定方式生成 value为方法的返回值
提示:
1. 若在同一个类中调用缓存方法 请使用AOP代理 否则无法使用缓存
2. @Cacheable: 若缓存存在,则使用缓存;不存在,则执行方法,并将结果存入缓存
@CacheEvit: 失效缓存(等于删除缓存)
@CachePut: 更新缓存(不管缓存存不存在,都会执行方法,然后更新缓存)
*/
//将过期时间设置为30s,方便我们测试
USER_CACHE("用户缓存", "userCache", 30, TimeUnit.SECONDS, 500, 1000);
/**
* 描述
*/
private String description;
/**
* 缓存名称
*/
private String cacheName;
/**
* 过期时间
*/
private long expireTime;
/**
* 时间单位
*/
private TimeUnit timeUnit;
/**
* 初始容量
*/
private int initialCapacity;
/**
* 最大缓存数量
*/
private long maximumSize;
}
4.caffeine基本配置
@Configuration
public class Config {
@Bean
public CacheManager caffeineCacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
List<CaffeineCache> caffeines = new ArrayList<CaffeineCache>();
for (CacheType type : CacheType.values()) {
CaffeineCache caffeineCache = new CaffeineCache(type.getCacheName(),
Caffeine.newBuilder()
//初始容量
.initialCapacity(type.getInitialCapacity())
//最大容量
.maximumSize(type.getMaximumSize())
//过期时间
.expireAfterWrite(type.getExpireTime(), type.getTimeUnit()).build());;
caffeines.add(caffeineCache);
}
cacheManager.setCaches(caffeines);
return cacheManager;
}
}
5.测试
5.1 Entity
@Data
@Builder
public class User {
private String name;
private Integer age;
}
5.2 Controller
@RestController
@RequestMapping
public class Controller {
@Resource
private UserService userService;
/**
* @param id id
* @return {@link User }
* @Description 演示获取用户并进行缓存
* @Date 2023/04/02 22:16
*/
@GetMapping("getUser")
public User getUser(@RequestParam Integer id) {
//循环10次,看控制台会不会打印十次user信息
for (int i = 0; i < 10; i++) {
User user = userService.getUser(id);
}
return userService.getUser(id);
}
/**
* @param id id
* @return {@link User }
* @Description 观看缓存
* @Author mouyang
* @Date 2023/04/02 22:17
*/
@GetMapping("watchCache")
public User watchCache(@RequestParam Integer id) {
return userService.watchCache(id);
}
}
5.3 Service
public interface UserService {
User getUser(Integer id);
User watchCache(Integer id);
}
5.3 ServiceImpl
@Service
public class UserServiceImpl implements UserService {
@Resource
private CacheManager cacheManager;
@Override
@Cacheable(cacheNames = "userCache", key = "#id")
public User getUser(Integer id) {
User user = User.builder()
.name("张三")
.age(23)
.build();
System.out.println("获得user: " + user);
return user;
}
@Override
public User watchCache(Integer id) {
Cache cache = cacheManager.getCache(CacheType.USER_CACHE.getCacheName());
Cache.ValueWrapper valueWrapper = cache.get(id);
User user = (User) valueWrapper.get();
System.out.println("从缓存中获取到id为+" + id + "的+user:" + user);
return user;
}
}
5.4 调用缓存方法二次
GET http://localhost:8080/getUser?id =1
多次调用结果会显示出:从缓存中获取到id为+1的+user:User(name=张三, age=23)
这样就实现了缓存的调用,只要缓存数据没有过期,都可以在不同接口中共用
6.Cachable 添加缓存注解的一些参数介绍
@Cacheable 是 Spring Framework 中的一个注解,它可以应用在方法上,用于声明该方法的结果可以被缓存起来,以便后续的调用可以直接返回缓存中的结果,而不必真正执行方法的代码。
@Cacheable 注解中的参数有以下几个:
value:缓存的名称,可以是一个字符串数组,表示该方法的结果可以被缓存到哪些缓存中。默认值为一个空数组,表示缓存到默认的缓存中。
key:缓存的 key,可以是一个 SpEL 表达式,表示缓存的 key 可以根据方法参数动态生成。默认值为一个空字符串,表示使用默认的 key 生成策略。
condition:缓存的条件,可以是一个 SpEL 表达式,表示缓存的结果是否应该被缓存。默认值为一个空字符串,表示不考虑任何条件,缓存所有结果。
unless:缓存的排除条件,可以是一个 SpEL 表达式,表示缓存的结果是否应该被排除在缓存之外。默认值为一个空字符串,表示不排除任何结果。
6.1 @Cacheable高级用法
1.指定缓存的key
@Cacheable(value = "myCache", key = "#id")
public String myMethod(int id) {
// ...
}
2.指定缓存条件
@Cacheable(value = "myCache", condition = "#result != null")
public String myMethod() {
// ...
}
3.指定缓存的过期时间
@Cacheable(value = "myCache", key = "#id", expire = 3600)
public String myMethod(int id) {
// ...
}
7. @CacheEvict注解,清除缓存参数介绍
value:缓存位置名称,不能为空,同上
key:缓存的key,默认为空,同上
condition:触发条件,只有满足条件的情况才会清除缓存,默认为空,支持SpEL
allEntries:true表示清除value中的全部缓存,默认为false
7.1 清除所有缓存
@CacheEvict(value="users", allEntries=true)
public void delete(Integer id) {
}
7.2 清除掉指定key的缓存
@CacheEvict(value="andCache",key="#user.userId + 'findById'")
public void modifyUserRole(SystemUser user) {
}
7.3 清除掉全部缓存
@CacheEvict(value="andCache",allEntries=true)
public final void setReservedUsers(String[] reservedUsers) {
}
8.@CachePut 更新缓存
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个
@CachePut(value=”my cache”)
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
@CachePut(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存
@CachePut(value=”testcache”,condition=”#userName.length()>2”)
8.1 更新缓存
@CachePut(value="accountCache",key="#account.getName()")// 更新accountCache 缓存
public Account updateAccount(Account account) {
return updateDB(account);
}
本文部分数据参考:原文链接:https://blog.csdn.net/weixin_51389615/article/details/129918956

浙公网安备 33010602011771号