美文网首页
spring boot2.0 redis升级

spring boot2.0 redis升级

作者: 木木_bfe8 | 来源:发表于2018-08-13 17:57 被阅读0次

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());
    }

}
```

相关文章

网友评论

      本文标题:spring boot2.0 redis升级

      本文链接:https://www.haomeiwen.com/subject/uhwhsftx.html