1、Redis的支持不仅仅是丰富了它的API,更是替换掉底层Jedis的依赖,取而代之换成了Lettuce(生菜) Lettuce基于Netty的连接实例
2、添加依赖。Lettuce貌似用到了commons-pool2
<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>
3、配置
spring.redis.host=localhost
spring.redis.port=6379
#spring.redis.password=root #根据需要
# 连接超时时间(毫秒)
spring.redis.timeout=10000
# Redis默认情况下有16个分片,这里配置具体使用的分片,默认是0
spring.redis.database=0
# 连接池最大连接数(使用负值表示没有限制) 默认 8
spring.redis.lettuce.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
spring.redis.lettuce.pool.max-wait=-1
# 连接池中的最大空闲连接 默认 8
spring.redis.lettuce.pool.max-idle=8
# 连接池中的最小空闲连接 默认 0
spring.redis.lettuce.pool.min-idle=0
4、代码
@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig {
/**
* 设置数据存入 redis 的序列化方式
*/
@Bean
RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory,Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
//连接
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
/**
* @功能描述 跟JacksonJsonRedisSerializer实际上是一样的
* 它不仅可以将对象序列化,还可以将对象转换为json字符串并保存到redis中,但需要和jackson配合一起使用。用JacksonJsonRedisSerializer序列化的话,
* 被序列化的对象不用实现Serializable接口。Jackson是利用反射和getter和setter方法进行读取的,如果不想因为getter和setter方法来影响存储,
* 就要使用注解来定义被序列化的对象。
* @param
* @return
*/
@Bean
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer(){
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
return jackson2JsonRedisSerializer;
}
/**
* 实例化 HashOperations 对象,可以使用 Hash 类型操作
*/
@Bean
public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForHash();
}
/**
* 实例化 ValueOperations 对象,可以使用 String 操作
*/
@Bean
public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForValue();
}
/**
* 实例化 ListOperations 对象,可以使用 List 操作
* @return
*/
@Bean
public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForList();
}
/**
* 实例化 SetOperations 对象,可以使用 Set 操作
*/
@Bean
public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForSet();
}
/**
* 实例化 ZSetOperations 对象,可以使用 ZSet 操作
*/
@Bean
public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForZSet();
}
}
/**
* 初始化redis监听容器,提供连接工厂、消息序列化方式
*
* @param connectionFactory redis连接工厂
* @return 监听bean
*/
@Bean
RedisMessageListenerContainer container(JedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setTopicSerializer(new StringRedisSerializer());
//可以添加多个 messageListener
// container.addMessageListener((message, pattern) -> {
//// Object parse = JSONObject.parse(new String(message.getBody()));
// log.info("parse result:{}", new String(message.getBody()));
// }, new PatternTopic(channelId));
return container;
}
简单包装
package com.lzls.springboot.redis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
/**
* @author yf
* redis Object Service 模板类
* 依赖ValueOperations接口,并实现部分功能,调用者需要指定具体的T类型。
* 主要用于存储简单的 <k,v>对象。如需增加其他操作,请自行补全此工具类(多key值操作,getAndSet,bit操作,操作字符串指定坐标内容)
* 提供单key值操作
* string append
* int提供redis原子操作
* @date 创建时间:2017年12月5日 上午11:01:00
* @version 1.0
*/
@Component
public class RedisObjectService<T> {
@Autowired
protected RedisTemplate<String, Object> redisTemplate;
@Resource
protected ValueOperations<String, T> valueOperations;
/**
* @功能描述 基本插入操作
* @param key
* @param obj
*/
public void set(String key,T obj){
RedisExceptionUtil.checkKeyException(key);
valueOperations.set(key, obj);
}
/**
* @功能描述
* @param key
* @param obj
* @param timeout 过期时间
* @param unit 时间类型TimeUnit 枚举类型
*/
public void set(String key,T obj,long timeout, TimeUnit unit){
RedisExceptionUtil.checkKeyException(key);
RedisExceptionUtil.checkObjectIsNull(unit);
//如果时间传入时间小于0。抛出不支持操作异常。
if(timeout<0){
throw new UnsupportedOperationException();
}
valueOperations.set(key, obj,timeout,unit);
}
/**
* @功能描述 根据key值获取指定对象
* @param key
* @return
*/
public T get(String key){
RedisExceptionUtil.checkKeyException(key);
return valueOperations.get(key);
}
/**
* @功能描述 给指定字符串后继续添加字符
* 因为需要判断T是否为String所以需要强制传入实际的T类型 (String.class)。
* 工具类GenericsUtils.getSuperClassGenricType只能通过子类获取父类模板的T类型。所以选择这种主动传入类类型模式
* @param key
* @param value
* @param clazz
*/
public void stringAppend(String key,String value,Class<T> clazz){
RedisExceptionUtil.checkKeyException(key);
//如果时间传入类型不为String。抛出不支持操作异常。
if(!clazz.getName().equals("java.lang.String")){
throw new UnsupportedOperationException();
}
valueOperations.append(key, value);
}
/**
* @功能描述 redis 自增操作
* @param key
* @param value
* @return
*/
public Long LongIncrement(String key,Long value){
//synchronized(RedisObjectService.class){
RedisExceptionUtil.checkKeyException(key);
return valueOperations.increment(key, value);
//}
}
/**
* @功能描述 redis 自增操作
* @param key
* @param value
* @return
*/
public Double DoubleIncrement(String key,Double value){
//synchronized(RedisObjectService.class){
RedisExceptionUtil.checkKeyException(key);
return valueOperations.increment(key, value);
//}
}
/**
* @功能描述 删除指定key
* @param key
*/
public void remove(String key){
RedisExceptionUtil.checkKeyException(key);
valueOperations.getOperations().delete(key);
}
/**
* @功能描述 判断key是否存在
* @param key
* @return
*/
public boolean exist(String key){
RedisExceptionUtil.checkKeyException(key);
if(get(key) != null){
return true;
}
return false;
}
}
单元测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTest {
// inject the actual template
@Autowired
private RedisObjectService<AttrBean> template;
@Test
public void sendTest() throws Exception {
AttrBean atr = new AttrBean();
atr.setItemid("1");
atr.setProdid("hello world");
template.set("hello",atr);
System.out.println("-----------------------------------------------------------");
System.out.println(template.get("hello"));
}
}
radis监听使用
@Log4j2
@Configuration
@Order(value = 4)
public class AppAttendanceRecordStart implements CommandLineRunner {
@Resource
RedisTemplate<String, String> redisTemplate;
/**
* 注入频道监听bean,此bean在RedisConfig.container方法中初始化
*/
@Resource
RedisMessageListenerContainer container;
// @Resource
// private RabbitTemplate rabbitTemplate;
/**
* 暂时指定的考勤redis频道id
*/
private String channelId = "attendance-record";
@Override
public void run(String... args) throws Exception {
log.info("ApplicationRedisListenerStart");
// AttendanceRecordApi attendanceRecordApi = new AttendanceRecordApi(redisTemplate, channelId);
// attendanceRecordApi.listener();
// 开始监听channelId,可以根据需求,调整成动态监听频道
container.addMessageListener((message, pattern) -> {
// Object parse = JSONObject.parse(new String(message.getBody()));
log.info("parse result:{}", new String(message.getBody()));
}, new PatternTopic(channelId));
}
/**
* 测试代码
*/
@Scheduled(cron = "0/10 * * * * ?")
public void sendMessage() {
JSONObject json = new JSONObject();
json.put("name", "Mr.m");
json.put("time", new Date());
redisTemplate.convertAndSend(channelId, json.toJSONString());
// rabbitTemplate.convertAndSend("fanoutExchange","", json.toJSONString());
}
}
```
网友评论