springboot整合xxl-job项目使用(含完整代码)

前言:在之前的文章中,我写过springboot集成quartz框架在实际项目中的应用。但是由于quartz框架的一些缺点,而xxl-job能完美克服这些缺点,也是当前市面上使用相对较多的定时任务框架。xxl-job提供了调度中心控制台页面,对所有的定时任务进行统一配置管理。在我之前的文章中写了一篇搭建调度中心的详细过程:https://blog.csdn.net/qq798867485/article/details/131415408。有不会搭建的同学可以先搭建,因为要使用xxljob必须要有调度中心提供服务,下面就详细介绍springboot整合xxl-job项目使用。

一、整合xxl-job

引入xxljob的依赖
<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>2.3.1</version>
</dependency>
在yml加上xxljob的配置
xxl:
  job:
    admin:
   	# 调度中心服务部署的地址
      addresses: http://localhost:8022/xxl-job-admin 
    # 执行器通讯TOKEN,要和调度中心服务部署配置的accessToken一致,要不然无法连接注册
    accessToken: default_token777
    executor:
      # 执行器AppName
      appname: job-demo
      # 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
      address:
      ip:
      #执行器端口号:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
      port: 8889
      # 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
      logpath:
      # 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
      logretentiondays: 30
加上配置类,启动springboot项目时连接调度中心服务

XxlJobConfig.java

package com.example.xxjob.config;

import com.example.xxjob.job.DemoHandler;
import com.xxl.job.core.executor.XxlJobExecutor;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;

@Configuration
@Slf4j
public class XxlJobConfig {
    
    

    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses;

    @Value("${xxl.job.accessToken}")
    private String accessToken;

    @Value("${xxl.job.executor.appname}")
    private String appname;

    @Value("${xxl.job.executor.address}")
    private String address;

    @Value("${xxl.job.executor.ip}")
    private String ip;

    @Value("${xxl.job.executor.port}")
    private int port;

    @Value("${xxl.job.executor.logpath}")
    private String logPath;

    @Value("${xxl.job.executor.logretentiondays}")
    private int logRetentionDays;


    @Bean
    public XxlJobSpringExecutor xxlJobExecutor() {
    
    
        log.info(">>>>>>>>>>> start xxl-job config init. >>>>>>>>");
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
        xxlJobSpringExecutor.setAppname(appname);
        xxlJobSpringExecutor.setAddress(address);
        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setLogPath(logPath);
        xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
        log.info(">>>>>>>>>>> end xxl-job config init. >>>>>>>>");
        return xxlJobSpringExecutor;
    }
}

启动springboot应用就可以看到能够连接xxl-job调度中心

在这里插入图片描述

二、编写定时任务(无参)

创建一个service层的类,来模拟实际业务中service层的类的调用

package com.example.xxjob.service;

public interface UserService  {
    
    

    void demoJob();
}
package com.example.xxjob.service.impl;

import com.example.xxjob.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service("userService")
@Slf4j
public class UserServiceImpl implements UserService {
    
    
    @Override
    public void demoJob() {
    
    
        log.info(">>>>>>>>>> 开始处理实际业务逻辑 >>>>>>>>>>>>>>>");
        log.info(">>>>>>>>>> 完成处理实际业务逻辑 >>>>>>>>>>>>>>>");
    }
}

2.1 BEAN模式(类形式)(不推荐)

Bean模式任务,支持基于类的开发方式,每个任务对应一个Java类。

  • 优点:不限制项目环境,兼容性好。即使是无框架项目,如main方法直接启动的项目也可以提供支持,
  • 缺点:
    • 每个任务需要占用一个Java类,造成类的浪费;
    • 不支持自动扫描任务并注入到执行器容器,需要手动注入。

而且还有一个很不好的缺点,就是没法使用@Autowired 或者 @Resource 把bean注入,不然会报空指针异常

2.1.1 新建一个定时任务
package com.example.xxjob.job;

import com.example.xxjob.service.UserService;
import com.example.xxjob.service.impl.UserServiceImpl;
import com.xxl.job.core.handler.IJobHandler;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class DemoHandler extends IJobHandler {
    
    

    private final UserService userService = new UserServiceImpl();

    @Override
    public void execute() throws Exception {
    
    
        log.info(">>>>>>>>>> BEAN模式(类形式) 开始 >>>>>>>>>>>>>>>");
        userService.demoJob();
        log.info(">>>>>>>>>> BEAN模式(类形式) 成功 >>>>>>>>>>>>>>>");
    }
}

2.1.2 手动注入到执行器容器
XxlJobExecutor.registJobHandler("demoHandler", new DemoHandler());

在这里插入图片描述

2.1.3 到调度中心执行器管理–新增执行器(也就是你的应用程序)
AppName: 和项目中yml文件配置的appname 的值一致
名称: 测试应用
注册方式:
  -- 自动注册:就无需配置ip和端口
  -- 手动录入:需要把你项目中的ip(域名)和端口录入

在这里插入图片描述

2.1.3 到调度中心任务管理–新增定时任务(也就是项目中的定时任务)
执行器:定时任务所在的项目,跟上一步执行器的名称一致
调度类型:Core
core表达式:根据需求中定时任务实际情况定
运行模式: BEAN
JobHandler:demoHandler,跟注入到执行器容器名称一致
剩下的一些选项可以默认,也可以根据你实际情况定。

在这里插入图片描述

2.1.4 执行定时任务和查看日志

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.2 BEAN模式(方法形式)(推荐)

2.2.1 新建一个定时任务

package com.example.xxjob.job;

import com.example.xxjob.service.UserService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class DemoJob {

    @Autowired
    private UserService userService;

    @XxlJob("demoJobHandler")
    public void demoJobHandler() throws Exception {
        log.info(">>>>>>>>>> BEAN模式(类形式) 开始 >>>>>>>>>>>>>>>");
        userService.demoJob();
        log.info(">>>>>>>>>> BEAN模式(类形式) 成功 >>>>>>>>>>>>>>>");
    }
}

2.2.2 后续步骤和 “2.1 BEAN模式(类形式)”一致,新增定时任务,然后执行即可。

三、定时任务迁移(选)

这个需求的是,公司原先项目中的使用的定时任务框架是quartz,现在要全部改为整合xxl-job来管理所有的定时任务。

首先还是要部署调度中心,配置和新建执行器和之前的步骤是一样的。这里有所不同的是定义一个定时任务,通过传参就可以

知道执行定时任务的逻辑,减少定义多个handler方法。

创建一个定时任务handler
	@XxlJob("doJob")
    @Transactional(rollbackFor = Exception.class)
    public void doJob(){
    
    
        String jobParam = XxlJobHelper.getJobParam();
        try {
    
    
            if(StrUtil.isNotBlank(jobParam)){
    
    
                JSONObject jsonObject = JSONObject.parseObject(jobParam);
                if(Objects.nonNull(jsonObject)){
    
    
                    Object bean = SpringUtils.getBean(jsonObject.getString("bean"));
                    Method method = bean.getClass().getMethod(jsonObject.getString("method"));
                    logger.info("调度定时任务执行开始:{}",jobParam);
                    method.invoke(bean);
                    logger.info("调度定时任务执行结束:{}",jobParam);
                }
            }
        }catch (Exception e){
    
    
            logger.info("调度定时任务执行失败:{},原因是:{}",jobParam,e.getMessage());
            XxlJobHelper.handleFail();
        }

    }

在这里插入图片描述

批量新增任务(带参数)
JobHeadler: doJob
任务参数:{"bean":"userService","method":"demoJob"}
bean:为原先定时任务的类,method:为原先定时任务的方法

在这里插入图片描述

在这里插入图片描述

完整项目的代码:https://github.com/gorylee/learnDemo

猜你喜欢

转载自blog.csdn.net/qq798867485/article/details/131423174
今日推荐