SpringBoot2.x集成Redis之-缓存

it2026-02-06  0

前面讲了【第二章】SpringBoot2.x集成Redis , 以及SpringBoot中redis的基本使用. 本篇主要讲Redis数据库作为SpringBoot中缓存(Cache)的基本使用.

引入依赖

<!-- redis starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- lettuce pool 缓存连接池 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> 复制代码

不再需要引入其他依赖,SpringBoot导入spring-boot-starter-data-redis时, CacheManager默认使用RedisCache.

如果项目不是以Redis作为缓存,则需引入:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> 复制代码

application.yml配置

spring: redis: # Redis数据库索引(默认为0) database: 0 # Redis服务器连接端口 port: 6379 # Redis服务器地址 host: 127.0.0.1 # Redis服务器连接密码(默认为空) password: 123456 # 连接超时时间(毫秒) timeout: 5000 lettuce: # 关闭超时时间 shutdown-timeout: 100 pool: # 连接池最大连接数(使用负值表示没有限制) max-active: 8 # 连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: 10000 # 连接池中的最大空闲连接 max-idle: 8 # 连接池中的最小空闲连接 min-idle: 0 复制代码

开启缓存@EnableCaching, 并配置CacheManager,KeyGenerator

@EnableCaching: 开启缓存CacheManager: Spring缓存管理器KeyGenerator: Redis 缓存键生成策略, Spring 默认的DefaultKeyGenerator根据参数列表生成Key,当参数列表的值相同时是一样的 就会造成获取到错误的缓存数据 import com.alibaba.fastjson.JSONObject; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.KeyGenerator; 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.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.time.Duration; import java.util.StringJoiner; /** * @Title: RedisCacheConfig * @Description: TODO(reids缓存配置) * @Author flyingkid * @Date 2019/6/5下午 11:36 */ @EnableCaching @Configuration public class RedisCacheConfig extends CachingConfigurerSupport { /** * @description TODO 缓存key前缀 */ private static final String keyPrefix = "CACHE:"; /** * 缓存生成key的策略 */ @Bean @Override public KeyGenerator keyGenerator() { return (target, method, params) -> { StringJoiner joiner = new StringJoiner(":",keyPrefix,""); joiner.add(target.getClass().getSimpleName()); joiner.add(method.getName()); for (Object param : params) { joiner.add(JSONObject.toJSONString(param)); } return joiner.toString(); }; } /** * RedisTemplate配置 */ @Bean public RedisTemplate<String,Object> redisTemplate(LettuceConnectionFactory factory){ RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(factory); redisTemplate.setKeySerializer(keySerializer()); redisTemplate.setHashKeySerializer(keySerializer()); redisTemplate.setValueSerializer(valueSerializer()); redisTemplate.setHashValueSerializer(valueSerializer()); return redisTemplate; } /** * 管理缓存 */ @Bean @Primary public CacheManager cacheManager(LettuceConnectionFactory factory){ //缓存配置对象 RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig() //设置缓存的默认超时时间:30分钟 .entryTtl(Duration.ofMinutes(30L)) //如果是空值,不缓存 .disableCachingNullValues() //设置key序列化器 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer())) //设置value序列化器 .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer((valueSerializer()))); return RedisCacheManager .builder(RedisCacheWriter.nonLockingRedisCacheWriter(factory)) .cacheDefaults(cacheConfig).build(); } /** * key序列化 */ private RedisSerializer<String> keySerializer() { return new StringRedisSerializer(); } /** * value序列化 */ private RedisSerializer<Object> valueSerializer() { return new GenericJackson2JsonRedisSerializer(); } } 复制代码

注: StringJoiner是 java8对String字符串拼接提供的工具类, new StringJoiner(":",keyPrefix,""); 构造器第一个参数表示拼接以冒号分隔,参数二是前缀,参数三是后缀. 感兴趣的小伙伴可以阅读下java.util.StringJoiner源码.

缓存基本使用

import lombok.extern.slf4j.Slf4j; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; /** * @ClassName: ExampleService * @Description: TODO redis缓存 * @Author: 爱飘de小子 */ @Slf4j @Service @CacheConfig(keyGenerator = "keyGenerator") //这是本类统一key生成策略 public class ExampleService { /** * @description TODO 添加缓存 * @param name */ @Override @Cacheable(value = "addCache") public String addCache(String name) { return "爱飘de小子"; } /** * @description TODO 删除缓存 * @param name */ @Override @CacheEvict(value = "addCache",allEntries=true) public void delCache(String name) { } } 复制代码

 


 

缓存注解详解

@Cacheable

添加在方法上,根据条件添加缓存

value: 缓存的名称,不能为空cacheNames: 缓存的名称,和value二选一key: 缓存的key,默认为空,表示使用方法的参数类型及参数值作为key,支持SpELkeyGenerator: 指定key的生成策略cacheManager: 指定缓存管理器cacheResolver: 指定获取解析器condition: 条件符合则缓存unless: 条件符合则不缓存sync: 是否使用异步模式 默认false

@CachePut

添加在方法上,根据条件添加缓存

@CachePut作用和@Cacheable类似,区别是@Cacheable没有缓存数据会执行方法后,把结果缓存起来,第二次调用方法不执行方法,直接从缓存中获取数据并返回. @CachePut每次都会执行方法,不管缓存中有没有数据,都会把结果缓存. 复制代码

@CacheEvict

添加在方法上,根据条件清空缓存.

value: 缓存名称,不能为空cacheNames: 缓存的名称,与value二选一keyGenerator: key的生成器。key/keyGenerator二选一使用condition: 触发条件,支持SpELallEntries: true表示清除value中的全部缓存,默认为falsebeforeInvocation: 是否在方法执行前就清空 默认falsecacheManager: 指定缓存管理器cacheResolver: 或者指定获取解析器

@CacheConfig

作用在类上,为本类的缓存注解配置全局属性

cacheNames: 缓存名称keyGenerator: key的生成器cacheManager: 缓存管理器cacheResolver: 获取解析器

@Caching

组合多个缓存注解

@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Caching { Cacheable[] cacheable() default {}; CachePut[] put() default {}; CacheEvict[] evict() default {}; } 复制代码

Caching注解中Cacheable,CachePut,CacheEvict都是数组类型. 可以满足方法添加或者删除多个缓存.

最新回复(0)