Spring Cache是Spring提供的通用缓存框架。它利用了AOP,实现了基于注解的缓存功能,使开发者不用关心底层使用了什么缓存框架,只需要简单地加一个注解,就能实现缓存功能了。用户使用Spring Cache,可以快速开发一个很不错的缓存功能
实现缓存逻辑有2种方式:
-
每个接口单独控制缓存逻辑
-
统一控制缓存逻辑
Spring从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口来统一不同的缓存技术;并支持使用JCache(JSR-107)注解简化我们开发;
-
Cache接口为缓存的组件规范定义,包含缓存的各种操作集合;
-
Cache接口下Spring提供了各种xxxCache的实现;如RedisCache,EhCacheCache ,ConcurrentMapCache等;
-
每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否已经被调用过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓存结果后返回给用户。下次调用直接从缓存中获取。
-
使用Spring缓存抽象时我们需要关注以下两点;
1、确定方法需要被缓存以及他们的缓存策略
2、从缓存中读取之前缓存存储的数据
内部使用AOP的形式,对redis操作进行简化
1.1、重要概念
名称 | 解释 |
---|---|
@Cacheable | 主要针对方法配置,能够根据方法的请求参数对其进行缓存 |
@CacheEvict | 清空缓存 |
1.2、入门案例
1.2.1 导入依赖
导入SpringDataRedis的依赖,并在application.yml中配置
<!--SpringDataRedis依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-dataredis</artifactId>
</dependency>
spring:
redis:
port: 6379
host: 192.168.136.160
1.2.2 开启缓存支持
然后在启动类注解@EnableCaching开启缓存
@SpringBootApplication
@EnableCaching //开启缓存
public class DemoApplication{
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
1.2.3 编写UserInfoService
@Service
public class UserInfoService {
//根据id查询
public UserInfo queryById(Long userId) {
//从数据库查询
UserInfo user = new UserInfo();
user.setId(userId);
user.setNickname("ceshi");
return user;
}
//根据id修改
public void update(Long userId) {
UserInfo user = new UserInfo();
user.setId(userId);
user.setNickname("itcast");
}
}
1.2.3 缓存@Cacheable
@Cacheable
注解会先查询是否已经有缓存,有会使用缓存,没有则会执行方法并缓存。
@Cacheable(value = "user",key = "#userId")
public UserInfo queryById(Long userId) {
//从数据库查询
UserInfo user = new UserInfo();
user.setId(userId);
user.setNickname("ceshi");
return user;
}
此处的value
是必需的,它指定了你的缓存存放在哪块命名空间。
此处的key
是使用的spEL表达式,参考上章。这里有一个小坑,如果你把methodName
换成method
运行会报错,观察它们的返回类型,原因在于methodName
是String
而methoh
是Method
。
此处的User
实体类一定要实现序列化public class User implements Serializable
,否则会报java.io.NotSerializableException
异常。
到这里,你已经可以运行程序检验缓存功能是否实现。
1.2.4 清除@CacheEvict
@CachEvict
的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空 。
//根据id修改
@CacheEvict(value = "user",key = "#userId")
public void update(Long userId) {
//修改用户
UserInfo user = new UserInfo();
user.setId(userId);
user.setNickname("itcast");
}
1.2.5 @CachePut
加了@CachePut注解的方法,会把方法的返回值put到缓存里面缓存起来,供其它地方使用。
@Cacheput("user")
public User findById(Long id) {
return userDao.findById(id);
}
1.2.6 @Caching
Java代码中,同个方法,一个相同的注解只能配置一次。如若操作多个缓存,可以使用@Caching
public @interface Caching {
Cacheable[] cacheable() default {};
CachePut[] put() default {};
CacheEvict[] evict() default {};
}