Skip to content
java
### 定时任务架构

#### 类关系图

![](./images/xxljob-class.png)

##### 说明

> 1. TimedTaskJobHandler 定时执行任务
> 2. EveryHourExecute 等等接口,即为延时任务接口,其他地方实现接口即可实现调用
> 3. 其他实现 EveryHourExecute 等等接口 的类,即为定时任务的实际业务类,例如店铺评分计算、定时操作订单等等



#### 二开示例说明

1. 通过Autowired 注入接口的实现集合

2. @XxlJob("everyMinuteExecute") 即为xxljob的注解,告知调度中心,当前任务名称。

3. 调用任务前,需要对任务做非空判定,如果没有实现,那么代码就不要继续执行,以免带来其他后果

4.  执行期间,每个调度都需要有try catch 以防止前半段代码执行,后半段代码因为前端代码抛出的异常导致无法走下去

5. 返回 ReturnT.SUCCESS 及代表xxljob执行成功,调度中心也会记录成功。

6. xxljob定时任务 配置,主要在意address即可,这里配置的是xxljob的地址,其他东西xxljob会给我们维护好

    ```yaml
    xxl:
      job:
        admin:
          addresses: http://127.0.0.1:9001/xxl-job-admin
        executor:
          appname: xxl-job-executor-lilishop
          address:
          ip:
          port: 8891
          logpath: ./xxl-job/executor
          logretentiondays: 7
    ```

    

7. 具体示例如下:

    1. 调度层

    ```java
     @Autowired(required = false)
         private List<EveryMinuteExecute> everyMinuteExecutes;
         /**
          * 每分钟任务
          *
          * @throws Exception
          */
         @XxlJob("everyMinuteExecute")
         public ReturnT<String> everyMinuteExecute(String param)  {
             log.info("每分钟任务执行");
             if (everyMinuteExecutes == null || everyMinuteExecutes.size() == 0) {
                 return ReturnT.SUCCESS;
             }
    
             for (int i = 0; i < everyMinuteExecutes.size(); i++) {
                 try {
                     everyMinuteExecutes.get(i).execute();
                 } catch (Exception e) {
                     log.error("每分钟任务异常", e);
                 }
             }
             return ReturnT.SUCCESS;
         }
    ```
    
    2. 具体逻辑执行层
    
    ```java
        /**
         * 订单自动取消(每分钟执行)
         *
         * @author paulG
         * @date 2021/3/11
         **/
        @Slf4j
        @Component
        @RequiredArgsConstructor(onConstructor = @__(@Autowired))
        public class CancelOrderTaskExecute implements EveryMinuteExecute {
            //订单
            private final OrderService orderService;
            //设置
            private final SettingService settingService;
          
            @Override
            public void execute() {
            Setting setting = settingService.get(SettingEnum.ORDER_SETTING.name());
                OrderSetting orderSetting = JSONUtil.toBean(setting.getSettingValue(), OrderSetting.class);
            if (orderSetting != null && orderSetting.getAutoCancel() != null) {
                    // 订单自动取消时间 = 当前时间 - 自动取消时间分钟数
                    DateTime cancelTime = DateUtil.offsetMinute(DateUtil.date(), -orderSetting.getAutoCancel());
                    LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(Order::getOrderStatus, OrderStatusEnum.UNPAID.name());
                    // 订单创建时间 <= 订单自动取消时间
                    queryWrapper.le(Order::getCreateTime, cancelTime);
                    List<Order> list = orderService.list(queryWrapper);
                    List<String> cancelSnList = list.stream().map(Order::getSn).collect(Collectors.toList());
                    for (String sn : cancelSnList) {
                        orderService.systemCancel(sn, "超时未支付自动取消");
                    }
                }
            }
        }
    ```
    
    
    xxxxxxxxxx     // 延时任务执行    public void onMessage(TimeTriggerMsg timeTriggerMsg) {        try {            String key = TimeTriggerUtil.generateKey(timeTriggerMsg.getTriggerExecutor(), timeTriggerMsg.getTriggerTime(), timeTriggerMsg.getUniqueKey());            if (cache.get(key) == null) {                log.info("执行器执行被取消:{} | 任务标识:{}", timeTriggerMsg.getTriggerExecutor(), timeTriggerMsg.getUniqueKey());                return;            }            log.info("执行器执行:" + timeTriggerMsg.getTriggerExecutor());            log.info("执行器参数:" + JSONUtil.toJsonStr(timeTriggerMsg.getParam()));            cache.remove(key);            TimeTriggerExecutor executor = (TimeTriggerExecutor) SpringContextUtil.getBean(timeTriggerMsg.getTriggerExecutor());            executor.execute(timeTriggerMsg.getParam());        } catch (Exception e) {            log.error("mq延时任务异常", e);        }    }java