一、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
二、修改yml
spring:
redis:
host: 127.0.0.1 #主机地址
port: 6379 #端口号
password: 123456 #密码(没有则不写)
jedis:
pool:
max-active: 8
max-wait: -1
max-idle: 500
min-idle: 0
lettuce:
shutdown-timeout: 0
三、引入配置文件
1)、redis主配置文件
package com.hq.redis.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate redisTemplate = new RedisTemplate();
redisTemplate.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory());
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));
return new CustomRedisCacheManager(redisCacheWriter, redisCacheConfiguration);
}
}
2、过期时间配置
package com.hq.redis.config;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import java.time.Duration;
public class CustomRedisCacheManager extends RedisCacheManager {
public CustomRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
super(cacheWriter, defaultCacheConfiguration);
}
/**
* 重新创建缓存的方法
* @param name
* @param cacheConfig
* @return
*/
@Override
protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
//名称中存在#标记进行到期时间配置
if (!name.isEmpty() && name.contains("#")) {
String[] SPEL = name.split("#");
//配置缓存到期时间
int cycle = Integer.parseInt(SPEL[1]);
//单位
String type = SPEL[2];
long time = 0;
switch (type) {
case "s"://秒
time = cycle;
break;
case "m"://分
time = 60 * cycle;
break;
case "h"://时
time = 60 * 60 * cycle;
break;
case "d"://天
time = 24 * 60 * 60 * cycle;
break;
}
return super.createRedisCache(SPEL[0], cacheConfig.entryTtl(Duration.ofSeconds(time)));
}
return super.createRedisCache(name, cacheConfig);
}
}
四、注解说明
1、@Cacheable
用于设置缓存,如果缓存不存在,则执行方法,然后根据方法的缓存值设置缓存,如果缓存存在,则直接获取缓存的值。
参数名 | 说明 | 示例 |
---|---|---|
value | key的名称,必须不为空,语法是key名#多少时间单位#时间单位,时间单位:(s:秒,m:分,h:时,d:天) | @Cacheable(value = “ssss#1#m”) |
key | 拼接的参数名,可以为空,如果不为空需按照spel表达式编写,如果为空,>如果不指定,则缺省按照方法的所有参数进行组合 | @Cacheable(value=”test”,key=”#test”) |
condition | 缓存的条件,可以为空,当条件为真时才进行缓存,语法按照Spel表达式编写 | @Cacheable(value = “test”,condition = “#id>2”) |
unless | 缓存的条件,可以为空,当条件为假时才进行缓存,语法按照Spel表达式编写 | @Cacheable(value = “test”,unless = “#id>2”) |
sync | 是否为异步,默认为false | @Cacheable(value = “test”,sync=true) |
2、@CachePut(更新缓存)
作用和@Cacheable一样,区别就是@CachePut一定会根据返回值重新设置缓存
3、@CacheEvict(删除缓存)
1)、value、 key 和 condition 参数配置和@Cacheable一样。
2)、allEntries
是否清空所有缓存内容,默认为 false,如果指定为 true,则方法调用后将立即清空所有缓存,
3)、beforeInvocation
是否在方法执行前清空缓存,默认为false,如果为false,则在方法执行后清空缓存,如果方法报了异常,则不会清空缓存。
4、@CacheConfig
作用于类,用于全局指定该类所有用到缓存注解的value,比如:@CacheConfig(cacheNames=“test”)
五、SpEL表达式说明
- #root.methodName:当前被调用的方法名
- #root.method.name:当前被调用的方法
- #root.target:当前被调用的目标对象
- #root.targetClass:当前被调用的目标对象类
- #root.arg[0]:当前被调用方法的参数列表
- #p0 :方法参数的值,0表示参数的索引
- #result :方法执行后的返回值
- #user.id:对象的属性也可以直接用#p0.id