1.配置:
POM:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.22</version>
</dependency>
yml:
server:
port: 7878
#Redis缓存配置
redis:
#监察员模式开关
usingSentinel: false
# Redis数据库索引(默认为0)
database: 0
# Redis服务器地址
host: 127.0.0.1
# Redis服务器连接端口
port: 6379
# 连接超时时间(毫秒)
timeout: 6000
# 连接池最大连接数(使用负值表示没有限制)
max-active: 50
# 连接池中的最大空闲连接
max-idle: 50
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: 3000
# 连接池中的最小空闲连接
min-idle: 10
#lua脚本位置
lua-path: script.lua
@Data
@ConfigurationProperties("redis")
public class RedisSetting {
private boolean usingSentinel;
private Integer database;
private String host;
private Integer port;
private Integer timeout;
private Integer maxIdle;
private Integer minIdle;
private Integer maxActive;
private Integer maxWait;
private String luaPath;
}
package com.cache.controller;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
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.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
import java.lang.reflect.Method;
import java.time.Duration;
@Configuration
@EnableCaching
@EnableConfigurationProperties({RedisSetting.class})
public class RedisConfig extends CachingConfigurerSupport {
private RedisSetting redisSetting;
public RedisConfig(RedisSetting redisSetting){
this.redisSetting = redisSetting;
}
/**
* 自定义生成redis-key
*
* @return
*/
@Override
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object o, Method method, Object... objects) {
StringBuilder sb = new StringBuilder();
sb.append(o.getClass().getName()).append(".");
sb.append(method.getName()).append(".");
for (Object obj : objects) {
sb.append(obj.toString());
}
System.out.println("keyGenerator=" + sb.toString());
return sb.toString();
}
};
}
@Bean
public JedisPoolConfig jedisPoolConfig(){
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(redisSetting.getMaxIdle());
jedisPoolConfig.setMinIdle(redisSetting.getMinIdle());
jedisPoolConfig.setMaxTotal(redisSetting.getMaxActive());
jedisPoolConfig.setMaxWaitMillis(redisSetting.getMaxWait());
return jedisPoolConfig;
}
@Bean
public JedisConnectionFactory jedisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(redisSetting.getHost());
redisStandaloneConfiguration.setDatabase(redisSetting.getDatabase());
redisStandaloneConfiguration.setPort(redisSetting.getPort());
JedisClientConfiguration.JedisClientConfigurationBuilder clientConfiguration = JedisClientConfiguration.builder();
clientConfiguration.connectTimeout(Duration.ofMillis(redisSetting.getTimeout()));
return new JedisConnectionFactory(redisStandaloneConfiguration, clientConfiguration.build());
}
@Override
@Bean
public CacheManager cacheManager() {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5));
return RedisCacheManager
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(jedisConnectionFactory()))
.cacheDefaults(redisCacheConfiguration).build();
}
@Bean(value = "redisTemplate")
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(jedisConnectionFactory());
// 开启事务支持
redisTemplate.setEnableTransactionSupport(true);
// 使用String格式序列化缓存键 shiro时 valid报错
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setDefaultSerializer(stringRedisSerializer);
redisTemplate.setValueSerializer(stringRedisSerializer);
return redisTemplate;
}
}
2.测试
@cacheable
@RestController
@RequestMapping("/redis")
public class Controller {
@GetMapping("/cache")
@Cacheable(value = "cache")
public String test(String name){
System.out.println("不适用缓存,进入方法。。。。。。。。。。。");
return "cache";
}
}
第一次调用:
第二次:
发现缓存成功,并且key是通过eyGenerator()才生成的
@Cacheable(value = "cache",key = "#name",condition = "#name.length()==4")
利用key支持el表达式,自己设定key值,并设置如name长度为4时候才使用缓存的条件
2.@CachePut
@CachePut(value = "cache",key = "#name")
每次都进入方法里,更新缓存
3.@CacheEvict
根据value的值来清除缓存
@CacheEvict(value = "cahe",key = "#name",allEntries = true)
allEntries:
是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存
beforeInvocation:
是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存
4.注意:return的值必须实现序列化,@Cacheable导入的包
import org.springframework.cache.annotation.Cacheable;