SpringBoot Cache 整合 Redis 缓存框架
作者:次时代小羊、来源:SpringBoot Cache 整合 Redis 缓存框架:https://blog.csdn.net/qq_45193304/article/details/131727266
作者:扛麻袋的少年、来源:@Cacheable注解属性介绍:https://blog.csdn.net/lzb348110175/article/details/105349109
SpringCache 官方文档:https://docs.spring.io/spring-framework/reference/integration/cache.html
SpringBoot 提供了 SpringBootCache 框架作为 SpringBoot 的缓存统一框架,使用 SpringBootCache ,我们可以使用注解的方式使用缓存,从而避免了写一些重复代码的问题。
SpringBoot 缓存,默认使用的是 ConcurrentMap 的方式来实现的,然而我们在项目中并不会这么使用。我们经常会引入第三方缓存框架,来完成对数据的缓存操作。比如说:Redis 。本文就来介绍 SpringBoot 整合 Redis 来实现数据的缓存。
1、引入依赖
首先我们需要引入相关的依赖,Cache 是缓存框架的核心依赖,不过该框架只提供了各种操作的接口集合,并没有具体的实现。
而接口之外,SpringBoot 提供了各种具体的实现,比如:RedisCache,EhCache,ConcurrentMapCache等等。
Redis 依赖是为了使用 Redis 作为缓存而引入的,如果不使用 Redis 作为缓存,也可以将 Redis 的依赖替换为其他实现。
Jackson 是作为序列化工具。
- Maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
- Gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-cache:2.7.3'
implementation 'org.springframework.boot:spring-boot-starter-data-redis:2.7.3'
implementation 'org.springframework.boot:spring-boot-starter-test:2.7.3'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3'
}
2、配置 Redis
因为我们引入了 SpringBoot Redis 的依赖,Spring 会默认使用 Redis 作为我们的缓存,所以需要配置 Redis 的信息。
- application.yaml
spring:
redis:
host: 127.0.0.1
port: 6379
- RedisCacheManager
@Configuration
public class RedisCacheConfig {
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
// 使用缓存的默认配置
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
// 使用 GenericJackson2JsonRedisSerializer 作为序列化器
config = config.serializeValuesWith(
RedisSerializationContext.SerializationPair.fromSerializer(
new GenericJackson2JsonRedisSerializer()));
RedisCacheManager.RedisCacheManagerBuilder builder =
RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config);
return builder.build();
}
}
3、启动类注解
使用 SpringBootCache 作为缓存框架,我们需要在 SpringBoot 的启动类上添加 @EnableCaching 注解,这样才能够启用缓存框架。
@EnableCaching
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
4、注解开发
我们只需要在方法上面添加相关的注解,即可使用缓存逻辑,从而提升服务性能。
1、@Cacheable(添加缓存)
该注解可以注解在方法和类上,当被注解的类下的方法或者被注解的方法被调用时,会先去缓存中查看是否有缓存数据,有缓存数据则直接返回缓存数据,无缓存数据则调用该方法,获取该方法的返回值,并将该返回值存入缓存中。
@Cacheable(value = "users", key = "#id")
public User getUserById(Long id) {
// 从数据库中读取用户信息
}
2、@CachePut(更新缓存)
该注解可以注解在方法和类上,当被注解的类下的方法或者被注解的方法被调用时,不管缓存中是否有对应的缓存数据,都会将该方法的返回值更新(插入或覆盖)到缓存中。
@CachePut(value = "users", key = "#user.id")
public User updateUser(User user) {
// 更新数据库中的用户信息
}
3、@CacheEvict(删除缓存)
该注解可以注解在方法和类上,当被注解的类下的方法或者被注解的方法被调用时,会直接删除缓存中的缓存数据。
@CacheEvict(value = "users", key = "#id")
public void deleteUserById(Long id) {
// 删除数据库中的用户信息
}
4、@Caching(组合注解)
该注解可以将多个缓存注解组合在一起使用。例如:
@Caching(
cacheable = @Cacheable(value = "users", key = "#id"),
put = @CachePut(value = "users", key = "#result.id"),
evict = @CacheEvict(value = "allUsers", allEntries = true)
)
public User getUserById(Long id) {
// 从数据库中读取用户信息
}
5、注解属性
@Cacheable,@CachePut,@CacheEvict三个注解都有一些属性。
1、cacheNames/value
用来指定缓存组件的名字。
@Cacheable(cacheNames = "user")
public User selectById(Integer id) {
return new User(id);
}
2、key
缓存数据时使用的 key,可以用它来指定。默认是使用方法参数的值。(这个 key 你必须使用 spEL 表达式来编写)
@Cacheable(cacheNames = "user", key = "#id")
public User selectById(Integer id) {
return new User(id);
}
使用以上的配置,如果入参的 id 值为 1,Redis 会存入一个 key 为 user::1 数据。
@Cacheable(cacheNames = "user", key = "#root.methodName")
public User selectById(Integer id) {
return new User(id);
}
使用以上的配置,如果入参的 id 值为 1,Redis 会存入一个 key 为 user::selectById 数据。
3、keyGenerator
key 的生成器。 key 和 keyGenerator 二选一使用。
@Bean
public KeyGenerator keyGenerator() {
return (target, method, params) -> Arrays.asList(params).toString();
}
使用以上的配置,如果入参的 id 值为 1,Redis 会存入一个 key 为 user::[1] 数据。
4、condition
可以用来指定符合条件的情况下才缓存。
@Cacheable(cacheNames = "user", key = "#id", condition = "#id > 1")
public User selectById(Integer id) {
return new User(id);
}
@Cacheable(cacheNames = "user", key = "#id", condition = "#id != null")
public User selectById(Integer id) {
return new User(id);
}
5、unless
该属性相当于 !condition 属性。否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。当然你也可以获取到结果进行判断。(通过 #result 获取方法结果)
@Cacheable(cacheNames = "user", key = "#id", unless = "#id > 1")
public User selectById(Integer id) {
return new User(id);
}
6、cacheManager
可以用来指定缓存管理器。从哪个缓存管理器里面获取缓存。针对不同的缓存技术,需要实现不同的 cacheManager,Spring 也为我们定义了如下的一些 cacheManger 实现()
| CacheManger | 描述 |
|---|---|
| SimpleCacheManager | 使用简单的Collection来存储缓存,主要用于测试 |
| ConcurrentMapCacheManager | 使用ConcurrentMap作为缓存技术(默认) |
| NoOpCacheManager | 测试用 |
| EhCacheCacheManager | 使用EhCache作为缓存技术,以前在hibernate的时候经常用 |
| GuavaCacheManager | 使用google guava的GuavaCache作为缓存技术 |
| HazelcastCacheManager | 使用Hazelcast作为缓存技术 |
| JCacheCacheManager | 使用JCache标准的实现作为缓存技术,如Apache Commons JCS |
| RedisCacheManager | 使用Redis作为缓存技术 |
7、sync
该属性用来指定是否使用异步模式,该属性默认值为 false,默认为同步模式。异步模式指定 sync = true 即可,异步模式下 unless 属性不可用。
当 sync 设置为 true 时,多个线程同时访问同一个未缓存的值时,会进行同步控制,以防止并发地加载相同的数据。
- 通常在缓存值的生成非常耗时时使用,以避免多个线程重复加载同一个值。
@Cacheable(value = "booksCache", sync = true)
public Book findBookByIsbn(String isbn) {
return bookRepository.findByIsbn(isbn);
}
6、SpEL 表达式
| 名字 | 位置 | 描述 | 示例 |
|---|---|---|---|
| methodName | root object | 当前被调用的方法名 | #root.methodName |
| method | root object | 当前被调用的方法 | #root.method.name |
| target | root object | 当前被调用的目标对象 | #root.target |
| targetClass | root object | 当前被调用的目标对象类 | #root.targetClass |
| args | root object | 当前被调用的方法的参数列表 | #root.args[0] |
| caches | root object | 当前方法调用使用的缓存列表(如 @Cacheable(value=[“cache1”,”cache2J),则有两个 cache) | #root.caches[0].name |
| argument name | evaluation context | 方法参数的名字,可以直接使用 #参数名,也可以使用 #p0 或 #a0 的形式,0代表参数的索引。 | #id、#p0、#a0 |
| result | evaluation context | 方法执行后的返回值 (仅当方法执行后的判断有效) | #result |
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 8629303@qq.com