SpringBoot配置redis作为定时器,实现订单超时提醒(含源码)

一、简介

  本次文章主要实现功能是接入redis作为定时器,倒计时实现订单超时未处理时,超时提醒。

  本次讲解中代码是在已经接入redis作为缓存的前提下进一步开发,具体可参考 SpringBoot配置redis作为缓存(含源码)

  使用步骤分别是①调用下单接口,存入redis数据 ② 调用订单处理接口,手动处理redis数据,手动处理后不再会有超时提醒 ③未处理的订单会自动监听超时提醒

二、使用前提

  在windows中启动redis和redis桌面管理工具,分享连接在文章最下方

三、实现效果

  

 

 

 三、代码实现步骤

  1.添加redis配置类

package com.cpl.tsl.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

/**
 * Redis配置类
 *
 * @author: lll
 * @date: 2022年03月07日 13:03:27
 */
@Configuration
public class RedisTaskConfig {
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {

        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        return container;
    }
}

  2.添加redis监听

package com.cpl.tsl.listener;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * RedisKey键监听以及业务逻辑处理
 *
 * @author: lll
 * @date: 2022年03月07日 14:03:49
 */
@Component
public class RedisTaskListener extends KeyExpirationEventMessageListener {

    private static final Logger logger = LoggerFactory.getLogger(RedisTaskListener.class);

    @Value("${applicationName:tsl}")
    private String applicationName;

    /**
     * @param listenerContainer 监听器
     */
    public RedisTaskListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    @Override
    public void onMessage(Message message, byte[] pattern) {
        String expiredKey = message.toString();
        // 将拿到的过期键使用之前拼接时的特殊符号分割成字符数组
        String[] expiredKeyArr = expiredKey.split("\\|");
        String businessSign = expiredKeyArr[0].toString();
        String expiredTimeSign = expiredKeyArr[1].toString();

        logger.info(businessSign +":"+ expiredTimeSign);
        Date date = new Date();
        // 只有本业务才执行以下操作
        if (businessSign.equals(applicationName + ":ORDERINFO")) {
            logger.info("订单超时,已取消");
        } else {
            logger.error("非订单业务不做处理");
        }
    }
}

  3.添加controller调动接口

package com.cpl.tsl.controller;


import com.cpl.tsl.utils.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.UUID;

/**
 * 测试类
 *
 * @author: lll
 * @date: 2021年06月02日 18:06:58
 */
@RestController
@RequestMapping("/")
@Api(tags = "测试模块")
public class TestController {

    private static final Logger logger = LoggerFactory.getLogger(TestController.class);

    @Resource
    private RedisTemplate<String, String> template;

    @Resource
    private RedisUtil redisUtil;

    @Value("${applicationName:tsl}")
    private String applicationName;


   

    /**
     * redis设置定时key,模拟订单下单,超时提醒或者去掉订单
     *
     * @param
     * @return java.lang.String
     * @author: lll
     * @date: 2022年03月07日 13:03:59
     */
    @RequestMapping(value = "/putkeys", method = RequestMethod.POST)
    @ApiOperation(value = "测试redis存储参数", notes = "测试redis存储参数")
    public String putRedisTaskKeys() {

        /**
         * 存入订单信息
         */
        Date date = new Date();
        //设置超时时间30秒
        Long overTime = new Long(30);
        //创建订单号
        String orderNo = UUID.randomUUID().toString();
        //订单信息
        String orderInfo = "这是订单号为:" + orderNo + " 的订单,价格是:2000元,下单时间是:" + date;
        //redis key
        String redisKey = applicationName + ":ORDERINFO|" + orderNo;
        redisUtil.set(redisKey, orderInfo, overTime);
        logger.info("下单时间:" + date);
        logger.info("订单的redisKey " + redisKey + " 订单信息 " + orderInfo);
        return "下单成功";
    }

    /**
     * 手动处理订单,从redis移除订单
     *
     * @param orderNo 订单号
     * @return java.lang.String
     * @author: lll
     * @date: 2022年03月07日 14:03:58
     */
    @RequestMapping(value = "/removeKeys", method = RequestMethod.POST)
    @ApiOperation(value = "测试redis移除参数", notes = "测试redis移除参数")
    public String removeRedisTaskKeys(@ApiParam(name = "orderNo", value = "订单号", required = true) @RequestParam("orderNo") String orderNo) {
        /**
         * 处理订单
         */
        //拼接redis key
        String redisKey = applicationName + ":ORDERINFO|" + orderNo;
        //删除redis key
        redisUtil.del(redisKey);
        logger.info("订单redisKey " + redisKey + " 已处理");
        return "处理完成";
    }


}

四、资源

源码:https://github.com/CodingPandaLLL/tsl.git

源码压缩包地址:https://codeload.github.com/CodingPandaLLL/tsl/zip/refs/tags/1.0.4

软件:Redis(提取码:vkun)Redis Desktop Manager(提取码:2syd)

 

posted @ 2022-03-07 16:30  CodingPanda  阅读(4290)  评论(0编辑  收藏  举报