一、集成redis及配置订阅代码
1.redis参数配置
2.redis配置类
package com.esgcc.redis;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.StringRedisSerializer;
/**
* 类 名: RedisConfig
* 描 述:
* 作 者:
* 创 建: 2020/5/26 11:36
* 邮 箱:
*/
@Slf4j
@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig {
/**
* 配置自定义redisTemplate
*
* @return
*/
@Bean
RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper);
template.setValueSerializer(serializer);
//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
}
3.redis工具类
package com.esgcc.redis;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* redis 工具类
*
* @author djk
*/
@Slf4j
@Service
public class RedisService {
private RedisTemplate<String, ?> redisTemplate;
public RedisTemplate<String, ?> getRedisTemplate() {
return redisTemplate;
}
@Resource(name = "redisTemplate")
public void setRedisTemplate(RedisTemplate<String, ?> redisTemplate) {
this.redisTemplate = redisTemplate;
}
/**
* 根据key删除缓存
*
* @param key
* @return
*/
public void delete(final String key) {
try {
redisTemplate.delete(key);
} catch (Exception e) {
log.error("Delete cache fail and key : " + key);
}
}
/**
* 保存数据到redis中
*/
public boolean put(final String key, final Serializable value) {
try {
return redisTemplate.execute((RedisCallback<Boolean>) connection -> {
connection.set(redisTemplate.getStringSerializer().serialize(key),
new JdkSerializationRedisSerializer().serialize(value));
return true;
});
} catch (Exception e) {
log.error("Put value to redis fail...", e);
}
return false;
}
/**
* 保存字符串到redis中
*/
public boolean setString(final String key, final String value) {
try {
return redisTemplate.execute((RedisCallback<Boolean>) redisConnection -> {
redisConnection.set(redisTemplate.getStringSerializer().serialize(key),
redisTemplate.getStringSerializer().serialize(value));
return true;
});
} catch (Exception e) {
log.error("putString value to redis fail...", e);
}
return false;
}
public boolean hset(final String key, final String field, final String value) {
try {
return redisTemplate.execute((RedisCallback<Boolean>) redisConnection ->
redisConnection.hSet(redisTemplate.getStringSerializer().serialize(key),
redisTemplate.getStringSerializer().serialize(field),
redisTemplate.getStringSerializer().serialize(value)));
} catch (Exception e) {
log.error("hset value to redis fail...", e);
}
return false;
}
public String hget(final String key, final String field) {
try {
return redisTemplate.execute((RedisCallback<String>) redisConnection -> {
byte[] bytes = redisConnection.hGet(redisTemplate.getStringSerializer().serialize(key),
redisTemplate.getStringSerializer().serialize(field));
return null != bytes ? redisTemplate.getStringSerializer().deserialize(bytes) : null;
});
} catch (Exception e) {
log.error("hget value from redis fail...", e);
}
return null;
}
/**
* 从redis 中查询数据
*/
public Object get(final String key) {
try {
return redisTemplate.execute((RedisCallback<Object>) connection ->
new JdkSerializationRedisSerializer()
.deserialize(connection.get(redisTemplate.getStringSerializer().serialize(key))));
} catch (Exception e) {
log.error("Get value from redis fail...", e);
}
return null;
}
/**
* 从redis 中查询字符串对象
*/
public String getString(final String key) {
try {
return redisTemplate.execute((RedisCallback<String>) connection -> {
byte[] bytes = connection.get(redisTemplate.getStringSerializer().serialize(key));
return null != bytes ? redisTemplate.getStringSerializer().deserialize(bytes) : null;
});
} catch (Exception e) {
log.error("getString value from redis fail...", e);
}
return null;
}
public boolean hasKey(final String key) {
return redisTemplate.hasKey(key);
}
/**
* 以毫秒为单位设置key的超时时间
*
* @param key key
* @param expireTime 超时时间
* @return boolean
*/
public boolean expireByMilliseconds(String key, Long expireTime) {
return redisTemplate.expire(key, expireTime, TimeUnit.MILLISECONDS);
}
/**
* 以分钟为单位设置key的超时时间
*
* @param key key
* @param expireTime 超时时间
* @return boolean
*/
public boolean expireByMinutes(String key, Long expireTime){
return redisTemplate.expire(key, expireTime, TimeUnit.MINUTES);
}
/**
* 对存储在指定key的数值执行原子的加1操作
*
* @param key key
* @return
*/
public Long incrKey(String key) {
return redisTemplate.execute((RedisCallback<Long>) connection ->
connection.incr(redisTemplate.getStringSerializer().serialize(key))
);
}
/**
* 检测set集合中ke是否存在{@code value}
*
* @param key 键
* @param value 元素
*/
public boolean isMember(String key, String value) {
return redisTemplate.opsForSet().isMember(key, value);
}
/**
* 在set中添加元素
*
* @param key 键
* @param values 值
*/
public Long sadd(String key, String... values) {
SetOperations<String, Object> set = (SetOperations<String, Object>) redisTemplate.opsForSet();
return set.add(key, values);
}
/**
* 在set中移除元素
*
* @param key 键
* @param values 值
*/
public Long srem(String key, String... values) {
return redisTemplate.opsForSet().remove(key, values);
}
/**
* 获得set数据量
*
* @param key 键
* @return size
*/
public Long scard(String key) {
return redisTemplate.opsForSet().size(key);
}
/**
* 扫描出满足条件的key
*
* @param pattern 表达式
* @return keys
*/
public List<String> scan(String pattern) {
try {
Set<String> execute = redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match(pattern).count(10000).build());
Set<String> binaryKeys = new HashSet<>();
while (cursor.hasNext()) {
binaryKeys.add(new String(cursor.next()));
}
return binaryKeys;
});
return new ArrayList<>(execute);
} catch (Exception e) {
log.info("scan", e);
return new ArrayList<>(0);
}
}
/**
* 根据key的集合获取values
*
* @param set key数组
* @return value数组(顺序与key数组一致)
*/
public List<String> multiGetString(List<String> set) {
List<String> result = new ArrayList<>();
set.forEach(s -> result.add(this.getString(s)));
return result;
}
/**
*@Description TODO 接受监听到的消息
*@Param
* @param redis消息key值
*@Return
*@Author
*@Date 15:05 2020/5/25
*/
public void receiveMessage(String message) {
log.info("接收redis通道消息:"+message);
//业务逻辑调用区域
}
}
4.监听器及执行方法
/**
*@Description TODO 初始化监听器
*@Param
* @param
*@Return
*@Author
*@Date 15:13 2020/5/25
*/
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory redisConnectionFactory,
MessageListenerAdapter listenerAdapter,@Value("${spring.redis.listenerDatabase}") String dataBase) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisConnectionFactory);
//配置监听通道
container.addMessageListener(listenerAdapter,new PatternTopic("__keyevent@"+ dataBase +"__:expired"));// 通道的名字
return container;
}
/**
*@Description TODO 利用反射来创建监听到消息之后的执行方法
*@Param
* @param
*@Return
*@Author
*@Date 15:22 2020/5/25
*/
@Bean
MessageListenerAdapter listenerAdapter(RedisService receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}
二、配置redis开启过期通知
redis开启过期键通知
找到redis配置文件redis.conf,打开配置文件找到notify-keyspace-events
配置查看是否开启,默认是没有开启的,添加配置notify-keyspace-events Ex