Springboot integrated xxl-job project use (including complete code)

Preface: In the previous article, I wrote about the application of springboot integrated quartz framework in actual projects. However, due to some shortcomings of the quartz framework, xxl-job can perfectly overcome these shortcomings, and it is also a relatively large timing task framework currently on the market. xxl-job provides a dispatch center console page for unified configuration and management of all scheduled tasks. In my previous article, I wrote a detailed process of building a dispatch center: https://blog.csdn.net/qq798867485/article/details/131415408. Students who don’t know how to build can build it first, because to use xxljob, a dispatch center must provide services. The following will introduce the use of springboot integration xxl-job project in detail.

1. Integrate xxl-job

Introduce the dependency of xxljob
<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>2.3.1</version>
</dependency>
Add xxljob configuration to yml
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
Add the configuration class to connect the dispatching center service when starting the springboot project

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

Start the springboot application and you can see that you can connect to the xxl-job dispatch center

insert image description here

2. Write a scheduled task (no parameters)

Create a service layer class to simulate the call of the service layer class in the actual business

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 mode (class form) (not recommended)

Bean mode tasks support class-based development, and each task corresponds to a Java class.

  • Advantages: It does not limit the project environment and has good compatibility. Even frameworkless projects, such as those started directly by the main method, can provide support,
  • shortcoming:
    • Each task needs to occupy a Java class, resulting in a waste of classes;
    • Automatic scanning of tasks and injection into the executor container is not supported, manual injection is required.

And there is also a very bad disadvantage, that is, you cannot use @Autowired or @Resource to inject beans, otherwise a null pointer exception will be reported

2.1.1 Create a new scheduled task
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 Manual injection into the executor container
XxlJobExecutor.registJobHandler("demoHandler", new DemoHandler());

insert image description here

2.1.3 To the dispatch center executor management – ​​add an executor (that is, your application)
AppName: 和项目中yml文件配置的appname 的值一致
名称: 测试应用
注册方式:
  -- 自动注册:就无需配置ip和端口
  -- 手动录入:需要把你项目中的ip(域名)和端口录入

insert image description here

2.1.3 Go to the dispatch center task management – ​​add a scheduled task (that is, the scheduled task in the project)
执行器:定时任务所在的项目,跟上一步执行器的名称一致
调度类型:Core
core表达式:根据需求中定时任务实际情况定
运行模式: BEAN
JobHandler:demoHandler,跟注入到执行器容器名称一致
剩下的一些选项可以默认,也可以根据你实际情况定。

insert image description here

2.1.4 Execute scheduled tasks and view logs

insert image description here

insert image description here

insert image description here

2.2 BEAN mode (method form) (recommended)

2.2.1 Create a new scheduled task

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 The follow-up steps are consistent with "2.1 BEAN mode (class form)", add a scheduled task, and then execute it.

3. Scheduled task migration (optional)

This requirement is that the timed task framework used in the company's original project is quartz, and now it needs to be changed to integrate xxl-job to manage all timed tasks.

First of all, the dispatch center needs to be deployed, and the configuration and new executors are the same as the previous steps. The difference here is to define a timed task, which can be done by passing parameters

Know the logic of executing timed tasks, and reduce the definition of multiple handler methods.

Create a timed task 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();
        }

    }

insert image description here

Add tasks in batches (with parameters)
JobHeadler: doJob
任务参数:{"bean":"userService","method":"demoJob"}
bean:为原先定时任务的类,method:为原先定时任务的方法

insert image description here

insert image description here

Code for the complete project: https://github.com/gorylee/learnDemo

Guess you like

Origin blog.csdn.net/qq798867485/article/details/131423174