一、spring-boot-cache缓存
1、pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>2.6.7</version>
</dependency>
2、main启动类加入@EnableCaching
import org.springframework.cache.annotation.EnableCaching;
@EnableCaching
3、自定义缓存key的命名规则
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.lang.reflect.Method;
// 自定义缓存的 key生成
@Component
public class MyKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object o, Method method, Object... objects) {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(o.getClass().getSimpleName())
.append("_")
.append(method.getName())
.append("_")
.append(StringUtils.arrayToDelimitedString(objects, "_"));
return stringBuffer.toString();
}
}
4、在类上使用,访问类所有的方法都缓存
import com.pingan.domain.Student;
import com.pingan.mapper.StudentMapper;
import com.pingan.service.StudentService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
// 在类上加 @Cacheable 代表类下面所有的方法都缓存,cacheNames随便起,keyGenerator为自定义缓存key的bean
@Service("studentService")
@Cacheable(cacheNames = "StudentServiceCache",keyGenerator = "myKeyGenerator")
public class StudentServiceImpl implements StudentService {
@Resource
private StudentMapper studentMapper;
@Override
public Student queryById(Integer id) {
return this.studentMapper.queryById(id);
}
}
在方法上使用,访问此方法才会缓存
@Cacheable(cacheNames = "StudentServiceCache",keyGenerator = "myKeyGenerator")
public Student queryById(Integer id) {
return this.studentMapper.queryById(id);
}
5、在更新和插入的方法上加上 @CacheEvict 清空缓存
@CacheEvict(cacheNames = "StudentServiceCache",allEntries = true)
public Student insert(Student student) {
this.studentMapper.insert(student);
return student;
}
6、定时任务清缓存
通过定时任务去清缓存
@Autowired
private Demo01Controller demo01Controller;
@Scheduled(cron = "0/4 * * * * *")
public void test03() {
demo01Controller.test02(); // test02方法上有注解 @CacheEvict
}
二、spring-boot的文字说明
下SpringBoot的缓存方案,有自带的ConcurrentLinkedHashMap,还有主流的Guava、Caffeine、Ehcache作为入门,先拿自身的来玩玩,也就是ConcurrentLinkedHashMap
一、ConcurrentLinkedHashMap的使用
先简单说一下,此缓存保存在内存中,如果关闭或重启服务,缓存将被清除。如果要长久保存,可以结合Redis使用方式,很简单,抓住这几个注解关键词:@EnableCaching、@Cacheable、@CachePut、@CacheEvict
1.1 @EnableCaching
一般在启动基类上加上此注解,表示打开缓存功能
@SpringBootApplication
@EnableCaching // 打开缓存功能
public class DemoApplication {
}
1.2 @Cacheable
用在获取并缓存数据的方法上,表示此方法有缓存功能。当调用此方法时,会先从缓存中查找
- 如果缓存里有,就直接返回,不会运行方法内部语句;
- 如果没有,则执行方法内部语句,然后把返回值缓存起来
/** 临时用HashMap当作数据库 */
private HashMap<Integer, UserBean> users = new HashMap<>();
@Cacheable(cacheNames = "cacheModel", key = "#id", unless = "#result == null")
public UserBean getById(int id) {
System.out.println("CacheModel.getById:id=" + id);
UserBean user = new UserBean(id, "name_" + new Random().nextInt(100));
users.put(id, user);
return user;
}
1.3 @CachePut
用在更新缓存的方法上,表示更新缓存中的数据。
@CachePut(cacheNames = "cacheModel", key = "#user.id", unless = "#user == null")
public UserBean updateUser(UserBean user){
System.out.println("CacheModel.updateUser: user=" + user);
return users.put(user.getId(), user);
}
1.4 @CacheEvict
用在删除缓存的方法上,表示根据条件删除对应的缓存
@CacheEvict(cacheNames = "cacheModel", key = "#id")
public UserBean removeUser(int id) {
System.out.println("CacheModel.removeUser: id=" + id);
return users.remove(id);
}
如果要清除cacheNames指定名称的所有缓存,增加参数:allEntries = true
@CacheEvict(cacheNames = "cacheModel", allEntries = true)
public void clear() {
System.out.println("CacheModel.clear all");
}
@Caching这个注解
使用该注解,可以在一个方法或者类上同时指定多个Spring Cache相关的注解
可以指定cacheable、put和evict三个属性,分别对应相应的注解,如@Caching(cacheable = @Cacheable(“users”), evict = { @CacheEvict(“cache2”),@CacheEvict(value = “cache3”, allEntries = true) })
@CacheConfig这个注解
抽取类中的所有@CachePut@Cacheable@CacheEvict的公共配置
@Caching & @CacheConfig
@Caching设置方法的复杂缓存规则
@CacheConfig:抽取类中的所有@CachePut@Cacheable@CacheEvict的公共配置
一、简介
1、缓存介绍
Spring 从 3.1 开始就引入了对 Cache 的支持。定义了 org.springframework.cache.Cache
和 org.springframework.cache.CacheManager
接口来统一不同的缓存技术。并支持使用 JCache(JSR-107)
注解简化我们的开发。
其使用方法和原理都类似于 Spring 对事务管理的支持。Spring Cache 是作用在方法上的,其核心思想是,当我们在调用一个缓存方法时会把该方法参数和返回结果作为一个键值对存在缓存中。
2、Cache 和 CacheManager 接口说明
- Cache 接口包含缓存的各种操作集合,你操作缓存就是通过这个接口来操作的。
- Cache 接口下 Spring 提供了各种 xxxCache 的实现,比如:RedisCache、EhCache、ConcurrentMapCache
- CacheManager 定义了创建、配置、获取、管理和控制多个唯一命名的 Cache。这些 Cache 存在于 CacheManager 的上下文中。
小结:
每次调用需要缓存功能的方法时,Spring 会检查指定参数的指定目标方法是否已经被调用过,如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓存结果后返回给用户。下次调用直接从缓存中获取。
二、@Cacheable 注解使用详细介绍
1、缓存使用步骤
@Cacheable
这个注解,用它就是为了使用缓存的。所以我们可以先说一下缓存的使用步骤:
1、开启基于注解的缓存,使用
@EnableCaching
标识在 SpringBoot 的主启动类上。2、标注缓存注解即可
① 第一步:开启基于注解的缓存,使用 @EnableCaching
标注在 springboot 主启动类上
② 第二步:标注缓存注解
注:这里使用 @Cacheable
注解就可以将运行结果缓存,以后查询相同的数据,直接从缓存中取,不需要调用方法。
2、常用属性说明
下面介绍一下 @Cacheable
这个注解常用的几个属性:
cacheNames/value :用来指定缓存组件的名字
key :缓存数据时使用的 key,可以用它来指定。默认是使用方法参数的值。(这个 key 你可以使用 spEL 表达式来编写)
keyGenerator :key 的生成器。 key 和 keyGenerator 二选一使用
cacheManager :可以用来指定缓存管理器。从哪个缓存管理器里面获取缓存。
condition :可以用来指定符合条件的情况下才缓存
unless :否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。当然你也可以获取到结果进行判断。(通过 #result 获取方法结果)
sync :是否使用异步模式。
① cacheNames
用来指定缓存组件的名字,将方法的返回结果放在哪个缓存中,可以是数组的方式,支持指定多个缓存。
② key
缓存数据时使用的 key。默认使用的是方法参数的值。可以使用 spEL 表达式去编写。
③ keyGenerator
key 的生成器,可以自己指定 key 的生成器,通过这个生成器来生成 key。
这样放入缓存中的 key 的生成规则就按照你自定义的 keyGenerator 来生成。不过需要注意的是:
@Cacheable
的属性,key 和 keyGenerator 使用的时候,一般二选一。
④ condition
符合条件的情况下才缓存。方法返回的数据要不要缓存,可以做一个动态判断。
⑤ unless
否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。
⑥ sync
是否使用异步模式。默认是方法执行完,以同步的方式将方法返回的结果存在缓存中。
3、spEL 编写 key
前面说过,缓存的 key 支持使用 spEL 表达式去编写,下面总结一下使用 spEL 去编写 key 可以用的一些元数据:
标签:Cacheable,Spring,Boot,缓存,key,注解,方法,id From: https://blog.51cto.com/lenglingx/6390816