maven依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath />
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.49</version>
</dependency>
</dependencies>
application.yml
redis默认有16个库,序号从0到15
spring.redis.database=1,表示使用序号为1的库
spring.redis.password=123456,redis服务器配置了需要密码访问
spring.redis.port=6379,redis默认端口为6379
spring.redis.timeout=5000,redis客户端配置超时断开连接,单位毫秒,这个值设置的太少,会导致报错:
Redis command timed out;
nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out
spring:
redis:
database: 1
host: 10.97.13.97
port: 6379
password: 123456
timeout: 5000
pool:
max-active: 200
max-wait: -1
max-idle: 10
min-idle: 0
redis配置类
- @EnableCaching 启用缓存
- @EnableScheduling启用定时任务,用于清理缓存
/**
* redis 配置类 <br>
* 配置RedisTemplate<br>
* 配置缓存管理器<br>
* 配置定时清理缓存<br>
*
* @author zhengzc
*
*/
@Configuration
@EnableCaching
@EnableScheduling
public class RedisConfig {
@SuppressWarnings({"rawtypes", "unchecked"})
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
/**
* 缓存配置管理器
*/
@Bean
public CacheManager cacheManager(LettuceConnectionFactory lettuceConnectionFactory) {
// 以锁写入的方式创建RedisCacheWriter对象
RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(lettuceConnectionFactory);
// 创建默认缓存配置对象
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
// 设置默认超过期时间是30秒
config.entryTtl(Duration.ofSeconds(30));
// 自定义cacheConfig
Map<String, RedisCacheConfiguration> initialCacheConfigurations = new HashMap<>();
for (Map.Entry<String, Integer> entry : CacheExpiresMap.get().entrySet()) {
String key = entry.getKey();
Integer seconds = entry.getValue();
RedisCacheConfiguration initialCacheConfig = RedisCacheConfiguration.defaultCacheConfig();
initialCacheConfigurations.put(key, initialCacheConfig.entryTtl(Duration.ofSeconds(seconds)));
}
// 初始化RedisCacheManager
RedisCacheManager cacheManager = new RedisCacheManager(writer, config, initialCacheConfigurations);
return cacheManager;
}
// 自动清除缓存
// cacheEvict()方法就是实现缓存对象的自动清除的地方,@CacheEvict注解指明cacheNames中指定的缓存
// allEntries = true表示清除每个缓存中的所有实体
@CacheEvict(allEntries = true, cacheNames = {"HelloService", "xxxx"})
@Scheduled(fixedDelay = 60 * 1000)
public void cacheEvict() {
System.err.println("start to clear cache...");
}
}
/**
* 缓存Cacheable cacheNames过期时间
*
*/
public class CacheExpiresMap {
private static HashMap<String, Integer> map = new HashMap<>();
static {
map.put("dic", 60);
}
public static HashMap<String, Integer> get() {
return map;
}
}
工具类 RedisUtil
https://blog.csdn.net/qq_26264237/article/details/100533463
HelloServiceImpl
@Service
public class HelloServiceImpl implements HelloService {
@Autowired
private RedisUtil redisUtil;
@Override
public void sendMessage(Message msg) {
String jsonString = JSON.toJSONString(msg);
redisUtil.convertAndSend("TOPIC_USERNAME", jsonString);
}
@Override
public void sendMessage(String jsonString) {
redisUtil.convertAndSend("TOPIC_USERNAME", jsonString);
}
@Cacheable(cacheNames = "HelloService", sync = true, key = "'getByCache'.concat(#p0)")
@Override
public String getByCache(String name) {
System.err.println("查询数据库.....................");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(new Date()) + ":" + name;
}
}
HelloController
@RestController
public class HelloController {
@Autowired
private RedisUtil redisUtil;
@Autowired
private HelloService helloService;
/**
* 设置缓存
*
* @param key
* @param value
* @return
*/
@GetMapping("set")
Object set(String key, String value) {
redisUtil.set(key, value);
return redisUtil.get(key);
}
/**
* 取出缓存信息
*
* @param key
* @return
*/
@GetMapping("get")
Object get(String key) {
return redisUtil.get(key);
}
/**
* 获取service层的缓存,不存在则访问数据库
*
* @param name
* @return
*/
@GetMapping("getByCache")
Object getByCache(String name) {
String byCache = helloService.getByCache(name);
return byCache;
}
/**
* 清除key为HelloService的缓存
*
* @return
*/
@GetMapping("clearCache")
Object clearCache() {
redisUtil.del("HelloService");
return "成功清除缓存HelloService";
}
/**
* 发布订阅信息,由客户端监听该队列
*
* @param key
* @return
*/
@GetMapping("convertAndSend")
Object convertAndSend(String key) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("key", key);
helloService.sendMessage(jsonObject.toJSONString());
return System.currentTimeMillis();
}
}
测试结果
访问:http://localhost:8080/set?key=name&value=hello
访问:http://localhost:8080/get?key=name
用redis客户工具查看:
访问:http://localhost:8080/getByCache?name=小米
之后访问结果不变
系统设置1分钟清理一次缓存,清理缓存后,返回的结果发生变化
多次访问,redis客户端查看结果:
清理缓存:http://localhost:8080/clearCache