美文网首页
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