1--依赖
<!-- redis依赖包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
2--账号配置
#配置springCache的实现为redis
cache:
type: redis
#redis缓存配置
redis:
host: ip
port: 端口
password: 账号
timeout: 最大超时时间
pool:
max-wait: -1
max-idle: 10
min-idle: 0
3--配置消息订阅与发布及Redis过期时间
@Configuration
public class RedisCacheManagerConfig {
/**
* Redis配置消息订阅与发布
*监听了两个类,第一个为微信登录或者绑定微信的类,第二个为用户和管理员之间的聊天
*/
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter1,
MessageListenerAdapter listenerAdapter2) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(listenerAdapter1, new PatternTopic("频道1"));
container.addMessageListener(listenerAdapter2, new PatternTopic("频道2"));
return container;
}
//频道一 方法接受的函数为你的频道类,return 为你的频道类和具体方法
@Bean
MessageListenerAdapter listenerAdapter1(SendSmsUtil receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}
//例子2
@Bean
MessageListenerAdapter listenerAdapter2(SendSmsUtil receiver) {
return new MessageListenerAdapter(receiver, "receiveMessageChat");
}
@Bean
StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate(connectionFactory);
}
/**
* 以【类名+方法名+参数】为缓存的key值
*
* @return
*/
@Bean
public KeyGenerator keyGenerator() {
return (target, method, params) -> {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(".");
sb.append(method.getName());
for (Object obj : params) {
sb.append("#");
sb.append(obj == null ? "" : obj.toString());
}
return sb.toString();
};
}
/**
* @Description: 配置Redis过期时间,单位:毫秒
* @Date 11:38 2021/10/5
*/
@Bean
@Primary
public RedisCacheManager cacheManager1Month(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration config = instanceConfig(3600L * 24 * 30);
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(config)
.transactionAware()
.build();
}
private RedisCacheConfiguration instanceConfig(Long ttl) {
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(MapperFeature.USE_ANNOTATIONS, false);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
return RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(ttl))
.disableCachingNullValues()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
}
}
4--接受发送频道类
对指定发送消息
stringRedisTemplate.convertAndSend(Constant.REDIS_CHANNEL_CHAT, message);
//在普通类中,可以直接使用@Resource注入
//在WebSocket中使用这种注入方式
private StringRedisTemplate stringRedisTemplate = SpringUtils.getBean(RedisUtil.class).getStringRedisTemplate();
@Component
public class SendSmsUtil {
//这里的message要以Json的形式接受,接收到了以后可以对它进行 JsonObject转化为类
public void receiveMessage(String message) {
new WxWebSocket().sendMessageToUser(message);
}
}
6--工具类
@Data
@Log4j2
@Component
public class RedisUtil {
@Resource
private RedisTemplate redisTemplate;
@Resource
private StringRedisTemplate stringRedisTemplate;
/**
* @param key
* @return 获得值
* redis有五种数据类型 opsForValue表示是操作字符串类型
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 本来只可以放入string类型,但是我们配置了自动序列化所以这儿可以传入object
*
* @param key
* @param value
* @return
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
log.error("redis set value exception:{}", e);
return false;
}
}
/**
* 原子操作
*
* @param key
* @param value
* @param expire 过期时间 秒
* @return
*/
public boolean setex(String key, Object value, long expire) {
try {
//TimeUnit.SECONDS指定类型为秒
redisTemplate.opsForValue().set(key, value, expire, TimeUnit.SECONDS);
return true;
} catch (Exception e) {
log.error("redis set value and expire exception:{}", e);
return false;
}
}
/**
* 非原子操作
*
* @param key
* @param expire
* @return
*/
public boolean expire(String key, long expire) {
try {
//这儿没有ops什么的是因为每种数据类型都能设置过期时间
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
return true;
} catch (Exception e) {
log.error("redis set key expire exception:{}", e);
return false;
}
}
/**
* @param key
* @return 获取key的过期时间
*/
public long ttl(String key) {
return redisTemplate.getExpire(key);
}
/**
* @param keys 删除key 可变参数
*/
public void del(String... keys) {
if (keys != null && keys.length > 0) {
redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(keys));
}
}
/**
* @param key
* @param step 传入正数 就是加多少 传入负数就是减多少
* @return
*/
public long incrBy(String key, long step) {
return redisTemplate.opsForValue().increment(key, step);
}
/**
* @param key
* @param value
* @return 如果该key存在就返回false 设置不成功 key不存在就返回ture设置成功
*/
public boolean setnx(String key, Object value) {
return redisTemplate.opsForValue().setIfAbsent(key, value);
}
/**
* 原子操作
*
* @param key
* @param value
* @param expire 在上面方法加上过期时间设置
* @return
*/
public boolean setnxAndExpire(String key, Object value, long expire) {
return redisTemplate.opsForValue().setIfAbsent(key, value, expire, TimeUnit.SECONDS);
}
/**
* @param key
* @param value
* @return 如果该key存在就返回之前的value 不存在就返回null
*/
public Object getAndSet(String key, Object value) {
return redisTemplate.opsForValue().getAndSet(key, value);
}
/**
* @param key
* @return 判断key是否存在
*/
public boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
/***list的长度**/
public long llen(String key) {
return redisTemplate.opsForList().size(key);
}
/**
* 获取key中index位置的值,负数就反过来数,-1为最后一个
*
* @param key
* @param index
* @return
*/
public Object lgetByIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
log.error("redis lgetByIndex error,key:{},index:{}exception:{}", key, index, e);
return null;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @return
*/
public boolean lrpush(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
log.error("redis lrpush error,key:{},value:{}exception:{}", key, value, e);
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lrpush(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
log.error("redis lrpush error,key:{},value:{},timeL{},exception:{}", key, value, time, e);
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @return
*/
public boolean lrpush(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
log.error("redis lrpush error,key:{},value:{},exception:{}", key, value, e);
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lrpush(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
log.error("redis lrpush error,key:{},value:{},time:{},exception:{}", key, value, time, e);
return false;
}
}
/**
* 根据索引修改list中的某条数据
*
* @param key 键
* @param index 索引
* @param value 值
* @return
*/
public boolean lUpdateByIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
log.error("redis lUpdateByIndex error,key:{},index:{},value:{},exception:{}", key, index, value, e);
return false;
}
}
/**
* 移除N个值为value
*
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public long lrem(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
log.error("redis lrem error,key:{},count:{},value:{},exception:{}", key, count, value, e);
return 0;
}
}
/*****hash数据类型方法 opsForHash表示是操作字符串类型*****/
/**
* @param key 健
* @param field 属性
* @param value 值
* @return
*/
public boolean hset(String key, String field, Object value) {
try {
redisTemplate.opsForHash().put(key, field, value);
return true;
} catch (Exception e) {
log.error("redis hset eror,key:{},field:{},value:{}", key, field, value);
return false;
}
}
/**
* @param key
* @param field
* @param value
* @param seconds(秒) 过期时间
* @return
*/
public boolean hset(String key, String field, Object value, long seconds) {
try {
redisTemplate.opsForHash().put(key, field, value);
expire(key, seconds);//调用通用方法设置过期时间
return true;
} catch (Exception e) {
log.error("redis hset and expire eror,key:{},field:{},value:{},exception:{}", key, field, value, e);
return false;
}
}
/**
* 获取key中field属性的值
*
* @param key
* @param field
* @return
*/
public Object hget(String key, String field) {
return redisTemplate.opsForHash().get(key, field);
}
/**
* 获取key中多个属性的键值对,这儿使用map来接收
*
* @param key
* @param fields
* @return
*/
public Map<String, Object> hmget(String key, String... fields) {
Map<String, Object> map = new HashMap<>();
for (String field : fields) {
map.put(field, hget(key, field));
}
return map;
}
/**
* @param key 获得该key下的所有键值对
* @return
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
}