Heycm

Heycm

XXL-JOB 升级 SpringBoot3 小记

2024-06-08
XXL-JOB 升级 SpringBoot3 小记

前言

Spring Boot 3 出来很久了,XXL-JOB 迟迟没有更适配版本,最近在整理自己的技术栈,就浅浅把它包装一下切到 Spring Boot 3 版本吧~

XXL-JOB 分布式定时任务,这个原理不在此文了解内容,此文主要记录笔者将 XXL-JOB 在 Spring Boot 3 上应用遇到的一些问题。

版本关系

服务版本
Java21.0.3
Spring Boot3.2.4
Xxl-Job2.4.1

问题简述

我们都知道 XXL-JOB 分调度中心和执行器,由调度中心去调度任务,交由执行器去真正执行任务。
此次升级的过程呢,遇到的问题主要是集中在调度中心这边,拢共也就几个问题,大致是依赖版本要换新版, jdk 版本升级后,servlet 包改变,参数问题要加编译插件,还有一个就是 freemarker 读参数问题,待会一个个看。

准备工作

官方文档 https://www.xuxueli.com/xxl-job/ 自己看看官网就可以

下载源码

这边拿了截至目前最新tag版本 2.4.1 下载解压就行

image-1717907618626

初始化数据库

/xxl-job-2.4.1/doc/db/tables_xxl_job.sql

image-1717907707505

升级过程

首先配环境

idea 打开项目,先把 jdk 版本配上
image

依赖升级

去掉了一些不用搭理的,关注这几项变动的就行

xxl-job 根 pom 文件

Java编译版本调整,SpringBoot版本调整,Mybatis版本调整

<properties>
  <maven.compiler.source>21</maven.compiler.source>
  <maven.compiler.target>21</maven.compiler.target>

  <spring.version>6.1.5</spring.version>
  <spring-boot.version>3.2.4</spring-boot.version>

  <mybatis-spring-boot-starter.version>3.0.3</mybatis-spring-boot-starter.version>
  <mysql-connector-j.version>8.3.0</mysql-connector-j.version>

	<jakarta.annotation-api.version>3.0.0</jakarta.annotation-api.version>
</properties>

xxl-job-admin 项目 pom 文件

增加插件处理请求参数解析的问题

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.13.0</version>
    <configuration>
      <compilerArgs>
        <arg>-parameters</arg>
      </compilerArgs>
    </configuration>
  </plugin>
</plugins>

xxl-job-core 项目 pom 文件

去掉 javax.annotation-api 引入 jakarta.annotation-api

<!-- javax.annotation-api -->
<!--<dependency>
   <groupId>javax.annotation</groupId>
   <artifactId>javax.annotation-api</artifactId>
   <version>${javax.annotation-api.version}</version>
   <scope>provided</scope>
  </dependency>-->

<!-- jakarta.annotation-api -->
<dependency>
  <groupId>jakarta.annotation</groupId>
  <artifactId>jakarta.annotation-api</artifactId>
  <version>${jakarta.annotation-api.version}</version>
  <scope>provided</scope>
</dependency>

配置文件 application.properties

# management.server.servlet.context-path=/actuator
management.server.base-path=/actuator

# spring.resources.static-locations=classpath:/static/
spring.web.resources.static-locations=classpath:/static/

# 数据源对应调整
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root_pwd

部分 javax 包调整

将项目中所有的

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Cookie;
import javax.mail.internet.MimeMessage;

对应调整为

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.Cookie;
import jakarta.mail.internet.MimeMessage;

一键替换很方便

Freemarker 取值处理

在这个版本中 Request["XXL_JOB_LOGIN_IDENTITY"] 无法被识别,通过阅读源码我们知道,这个逻辑是在权限拦截器中登录认证成功后,将当前登录对象信息放到 request.attribute

PermissionInterceptor.java

if (needLogin) {
	XxlJobUser loginUser = loginService.ifLogin(request, response);
	if (loginUser == null) {
		response.setStatus(302);
		response.setHeader("location", request.getContextPath()+"/toLogin");
		return false;
	}
	if (needAdminuser && loginUser.getRole()!=1) {
		throw new RuntimeException(I18nUtil.getString("system_permission_limit"));
	}
	request.setAttribute(LoginService.LOGIN_IDENTITY_KEY, loginUser);
}

这样我们增加一下这里的逻辑,设置一个普通变量去存储认证状态就行

if (needLogin) {
	XxlJobUser loginUser = loginService.ifLogin(request, response);
	if (loginUser == null) {
		response.setStatus(302);
		response.setHeader("location", request.getContextPath()+"/toLogin");
		return false;
	}
	if (needAdminuser && loginUser.getRole()!=1) {
		throw new RuntimeException(I18nUtil.getString("system_permission_limit"));
	}
	request.setAttribute(LoginService.LOGIN_IDENTITY_KEY, loginUser);
    
	request.setAttribute("loginUserName", loginUser.getUsername());
	request.setAttribute("loginUserRole", loginUser.getRole());
}

Request["XXL_JOB_LOGIN_IDENTITY"] 处理

接着修改 Freemarker 文件,将Request["XXL_JOB_LOGIN_IDENTITY"] 做相关替换就好

Request["XXL_JOB_LOGIN_IDENTITY"].username 改为 loginUserName
Request["XXL_JOB_LOGIN_IDENTITY"].role 改为 loginUserRole

涉及两个文件

  • common.macro.ftl
  • joblog.index.ftl

到这呢就算升级完成了,启动项目测试

调度中心启动

image-1717909995131
image-1717910015756

执行器启动 xxl-job-executor-sample-springboot

image-1717910231189

可以看到,案例定时器都已注册成功,再看调度中心,执行器已自动注册成功

image-1717910361292

OK,到这本文完,至于测试案例,可以看官网,自己写写就行。