feat: xxz-job 调度中心首次提交
内容: 1. 核心包开发,注解开发 2. 任务扫描以及本地注册 3. 任务执行,任务支持本地单机调用 4. 样本执行器生成
This commit is contained in:
38
.gitignore
vendored
Normal file
38
.gitignore
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
||||||
53
pom.xml
Normal file
53
pom.xml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.xiang.pom</groupId>
|
||||||
|
<artifactId>xmc-web-starter</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.xiang</groupId>
|
||||||
|
<artifactId>xservice-quartz</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<modules>
|
||||||
|
<module>xservice-quartz-admin</module>
|
||||||
|
<module>xservice-quartz-core</module>
|
||||||
|
<module>xservice-quartz-common</module>
|
||||||
|
<module>xservice-quartz-sample</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.xiang.starter</groupId>
|
||||||
|
<artifactId>xmc-common</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.xiang.starter</groupId>
|
||||||
|
<artifactId>xmc-mysql-starter</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.xiang.starter</groupId>
|
||||||
|
<artifactId>xmc-cache-starter</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.xiang.starter</groupId>
|
||||||
|
<artifactId>xmc-logger-starter</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
22
xservice-quartz-admin/pom.xml
Normal file
22
xservice-quartz-admin/pom.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.xiang</groupId>
|
||||||
|
<artifactId>xservice-quartz</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.xiang.app</groupId>
|
||||||
|
<artifactId>xservice-quartz-admin</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.xiang.app;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-06 09:09
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableScheduling
|
||||||
|
public class Application {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(Application.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(Application.class, args);
|
||||||
|
log.info("✅✅✅X-service quartz 任务调度中心启动成功✅✅✅");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package com.xiang.app.quartz.admin.domain.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2025-12-30 09:42
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@TableName("xmc_quartz_config")
|
||||||
|
public class JobConfigDO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* id
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 应用名称
|
||||||
|
*/
|
||||||
|
private String applicationName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用地址
|
||||||
|
*/
|
||||||
|
private String applicationAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定时任务名称
|
||||||
|
*/
|
||||||
|
private String beanName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务执行调度时间
|
||||||
|
*/
|
||||||
|
private String cron;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类名
|
||||||
|
*/
|
||||||
|
private String clazz;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 方法
|
||||||
|
*/
|
||||||
|
private String method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务开关
|
||||||
|
* 0:关闭 1:开启
|
||||||
|
*/
|
||||||
|
private Integer jobSwitch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除标识(0:未删除 1:已删除)
|
||||||
|
*/
|
||||||
|
private Integer delFlag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上次执行时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime lastRunningTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.xiang.app.quartz.admin.domain.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-05 16:14
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class JobRunningLogDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* id
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务id
|
||||||
|
*/
|
||||||
|
private Long quartzId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime runningTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行状态(0:未执行 1:执行成功 2:执行失败)
|
||||||
|
*/
|
||||||
|
private Integer runningStatus;
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.xiang.app.quartz.admin.domain.req;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-05 15:49
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class TaskRegisterRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用名称
|
||||||
|
*/
|
||||||
|
private String applicationName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用地址
|
||||||
|
*/
|
||||||
|
private String applicationAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定时任务名称
|
||||||
|
*/
|
||||||
|
private String beanName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务执行调度时间
|
||||||
|
*/
|
||||||
|
private String cron;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类名
|
||||||
|
*/
|
||||||
|
private String clazz;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 方法
|
||||||
|
*/
|
||||||
|
private String method;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.xiang.app.quartz.admin.manage;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.xiang.app.quartz.admin.domain.entity.JobConfigDO;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-05 15:53
|
||||||
|
*/
|
||||||
|
public interface IQuartzConfigManage extends IService<JobConfigDO> {
|
||||||
|
|
||||||
|
|
||||||
|
List<JobConfigDO> selectByAppName(String name);
|
||||||
|
|
||||||
|
List<JobConfigDO> loadEnabledJobs();
|
||||||
|
|
||||||
|
boolean updateJobLastTriggerTime(String name, LocalDateTime now);
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.xiang.app.quartz.admin.manage;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.xiang.app.quartz.admin.domain.entity.JobConfigDO;
|
||||||
|
import com.xiang.app.quartz.admin.mapper.IQuartzConfigMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-05 15:53
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class QuartzConfigManageImpl extends ServiceImpl<IQuartzConfigMapper, JobConfigDO> implements IQuartzConfigManage {
|
||||||
|
@Override
|
||||||
|
public List<JobConfigDO> selectByAppName(String name) {
|
||||||
|
LambdaQueryWrapper<JobConfigDO> lqw = Wrappers.lambdaQuery();
|
||||||
|
lqw.eq(JobConfigDO::getApplicationName, name);
|
||||||
|
lqw.eq(JobConfigDO::getDelFlag, 0);
|
||||||
|
return baseMapper.selectList(lqw);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<JobConfigDO> loadEnabledJobs() {
|
||||||
|
LambdaQueryWrapper<JobConfigDO> lqw = Wrappers.lambdaQuery();
|
||||||
|
lqw.eq(JobConfigDO::getJobSwitch, 1);
|
||||||
|
lqw.eq(JobConfigDO::getDelFlag, 0);
|
||||||
|
return baseMapper.selectList(lqw);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateJobLastTriggerTime(String name, LocalDateTime now) {
|
||||||
|
LambdaUpdateWrapper<JobConfigDO> luw = Wrappers.lambdaUpdate();
|
||||||
|
luw.eq(JobConfigDO::getBeanName, name);
|
||||||
|
luw.set(JobConfigDO::getLastRunningTime, now);
|
||||||
|
return baseMapper.update(luw) > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.xiang.app.quartz.admin.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.xiang.app.quartz.admin.domain.entity.JobConfigDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-05 15:54
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
@Mapper
|
||||||
|
public interface IQuartzConfigMapper extends BaseMapper<JobConfigDO> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.xiang.app.quartz.admin.server;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-06 09:18
|
||||||
|
*/
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class XxzJobRegisterController {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.xiang.app.quartz.admin.service;
|
||||||
|
|
||||||
|
import com.xiang.app.quartz.admin.domain.req.TaskRegisterRequest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-05 15:51
|
||||||
|
*/
|
||||||
|
public interface ITaskConfigService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册单个任务
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean registerTask(TaskRegisterRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量注册任务
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean registerTasks(List<TaskRegisterRequest> request);
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
package com.xiang.app.quartz.admin.service.impl;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.xiang.app.quartz.admin.domain.entity.JobConfigDO;
|
||||||
|
import com.xiang.app.quartz.admin.domain.req.TaskRegisterRequest;
|
||||||
|
import com.xiang.app.quartz.admin.manage.IQuartzConfigManage;
|
||||||
|
import com.xiang.app.quartz.admin.service.ITaskConfigService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-05 15:52
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class TaskConfigServiceImpl implements ITaskConfigService {
|
||||||
|
|
||||||
|
private final IQuartzConfigManage quartzConfigManage;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean registerTask(TaskRegisterRequest request) {
|
||||||
|
return registerTasks(Collections.singletonList(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean registerTasks(List<TaskRegisterRequest> request) {
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(request)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String applicationName = request.get(0).getApplicationName();
|
||||||
|
List<JobConfigDO> jobs = quartzConfigManage.selectByAppName(applicationName);
|
||||||
|
Map<String, JobConfigDO> existJobs = Maps.newHashMap();
|
||||||
|
if (CollectionUtils.isNotEmpty(jobs)) {
|
||||||
|
existJobs.putAll(jobs.stream().collect(Collectors.toMap(JobConfigDO::getBeanName, Function.identity(), (a, b) -> a)));
|
||||||
|
}
|
||||||
|
List<JobConfigDO> insertList = Lists.newArrayList();
|
||||||
|
List<JobConfigDO> upudateList = Lists.newArrayList();
|
||||||
|
request.forEach(item -> {
|
||||||
|
if (existJobs.containsKey(item.getBeanName())) {
|
||||||
|
JobConfigDO jobConfigDO = existJobs.get(item.getBeanName());
|
||||||
|
putDataIntoDo(item, jobConfigDO, applicationName);
|
||||||
|
upudateList.add(jobConfigDO);
|
||||||
|
} else {
|
||||||
|
JobConfigDO jobConfigDO = new JobConfigDO();
|
||||||
|
putDataIntoDo(item, jobConfigDO, applicationName);
|
||||||
|
insertList.add(jobConfigDO);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (CollectionUtils.isNotEmpty(insertList)) {
|
||||||
|
quartzConfigManage.saveBatch(insertList);
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(upudateList)) {
|
||||||
|
quartzConfigManage.updateBatchById(upudateList);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void putDataIntoDo(TaskRegisterRequest item, JobConfigDO jobConfigDO, String applicationName) {
|
||||||
|
jobConfigDO.setApplicationName(applicationName);
|
||||||
|
jobConfigDO.setApplicationAddress(item.getApplicationAddress());
|
||||||
|
jobConfigDO.setBeanName(item.getBeanName());
|
||||||
|
jobConfigDO.setCron(item.getCron());
|
||||||
|
jobConfigDO.setClazz(item.getClazz());
|
||||||
|
jobConfigDO.setMethod(item.getMethod());
|
||||||
|
jobConfigDO.setJobSwitch(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.xiang.app.quartz.admin.utils;
|
||||||
|
|
||||||
|
import org.springframework.scheduling.support.CronExpression;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-05 16:16
|
||||||
|
*/
|
||||||
|
public class CronUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断:
|
||||||
|
* 从 lastTriggerTime 到现在
|
||||||
|
* cron 是否命中过至少一次
|
||||||
|
*/
|
||||||
|
public static boolean isMatch(String cron, LocalDateTime lastTriggerTime) {
|
||||||
|
if (cron == null || cron.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CronExpression expression = CronExpression.parse(cron);
|
||||||
|
|
||||||
|
ZoneId zoneId = ZoneId.systemDefault();
|
||||||
|
ZonedDateTime now = ZonedDateTime.now(zoneId);
|
||||||
|
|
||||||
|
// 第一次执行(从未触发过)
|
||||||
|
if (lastTriggerTime == null) {
|
||||||
|
// 给一个足够早的时间,防止任务永远不触发
|
||||||
|
ZonedDateTime base = now.minusYears(1);
|
||||||
|
ZonedDateTime next = expression.next(base);
|
||||||
|
return next != null && !next.isAfter(now);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZonedDateTime last = lastTriggerTime.atZone(zoneId);
|
||||||
|
ZonedDateTime next = expression.next(last);
|
||||||
|
|
||||||
|
return next != null && !next.isAfter(now);
|
||||||
|
}
|
||||||
|
}
|
||||||
34
xservice-quartz-admin/src/main/resources/application-dev.yml
Normal file
34
xservice-quartz-admin/src/main/resources/application-dev.yml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
group: DEFAULT_GROUP
|
||||||
|
namespace: 00131110-3ecb-4a35-8bbb-624edde1d937
|
||||||
|
server-addr: general.xiangtech.xyz:8848
|
||||||
|
username: nacos
|
||||||
|
password: nacos
|
||||||
|
datasource:
|
||||||
|
dynamic:
|
||||||
|
primary: master
|
||||||
|
datasource:
|
||||||
|
master:
|
||||||
|
url: jdbc:mysql://120.27.153.87:3306/xservice_quartz?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
|
||||||
|
username: quartz
|
||||||
|
password: quartz@123
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
sshConnect: false
|
||||||
|
|
||||||
|
redis:
|
||||||
|
host: r-bp1wt59a6nfyt4e3ltpd.redis.rds.aliyuncs.com
|
||||||
|
port: 6379
|
||||||
|
password: Xiang0000 # 如果无密码可以省略
|
||||||
|
database: 10
|
||||||
|
timeout: 5000
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
max-active: 8
|
||||||
|
max-idle: 8
|
||||||
|
min-idle: 0
|
||||||
|
max-wait: 1000
|
||||||
|
xxz-job:
|
||||||
|
appName: xservice-quartz-admin
|
||||||
9
xservice-quartz-admin/src/main/resources/application.yml
Normal file
9
xservice-quartz-admin/src/main/resources/application.yml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
server:
|
||||||
|
port: 30030
|
||||||
|
spring:
|
||||||
|
profiles:
|
||||||
|
active: dev
|
||||||
|
application:
|
||||||
|
name: xservice-quartz-admin
|
||||||
|
main:
|
||||||
|
allow-bean-definition-overriding: true
|
||||||
21
xservice-quartz-common/pom.xml
Normal file
21
xservice-quartz-common/pom.xml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.xiang</groupId>
|
||||||
|
<artifactId>xservice-quartz</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.xiang.starter</groupId>
|
||||||
|
<artifactId>xservice-quartz-common</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
||||||
35
xservice-quartz-core/pom.xml
Normal file
35
xservice-quartz-core/pom.xml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.xiang</groupId>
|
||||||
|
<artifactId>xservice-quartz</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.xiang.starter</groupId>
|
||||||
|
<artifactId>xservice-quartz-core</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.xiang.starter</groupId>
|
||||||
|
<artifactId>xmc-common</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.xiang.starter</groupId>
|
||||||
|
<artifactId>xmc-cache-starter</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.xiang.core.quartz.annotation;
|
||||||
|
|
||||||
|
import com.xiang.core.quartz.config.XxzJobAutoConfiguration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2025-12-30 10:49
|
||||||
|
*/
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Import(XxzJobAutoConfiguration.class)
|
||||||
|
public @interface EnableXxzJob {
|
||||||
|
String[] basePackages() default {};
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.xiang.core.quartz.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2025-12-30 08:48
|
||||||
|
*/
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface XxzJob {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bean的名称
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String name();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cron调度方法
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String cron();
|
||||||
|
|
||||||
|
boolean enabled() default true;
|
||||||
|
/**
|
||||||
|
* 是否支持多机分布式运行
|
||||||
|
* 若为false:每台机器都会执行一次
|
||||||
|
* 若为true:仅一台机器会执行
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean distributed() default true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.xiang.core.quartz.boostrap;
|
||||||
|
|
||||||
|
import com.xiang.core.quartz.holder.JobDefinitionHolder;
|
||||||
|
import com.xiang.core.quartz.model.JobDefinition;
|
||||||
|
import com.xiang.core.quartz.schedule.JobScheduler;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.ApplicationArguments;
|
||||||
|
import org.springframework.boot.ApplicationRunner;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-06 09:50
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class JobBootstrap implements ApplicationRunner {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private JobScheduler scheduler;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(ApplicationArguments args) {
|
||||||
|
JobDefinitionHolder.getAll()
|
||||||
|
.stream()
|
||||||
|
.filter(JobDefinition::isEnabled)
|
||||||
|
.forEach(scheduler::schedule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.xiang.core.quartz.config;
|
||||||
|
|
||||||
|
import com.xiang.core.quartz.executor.JobExecutor;
|
||||||
|
import com.xiang.core.quartz.model.XxzJobProperties;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-06 09:29
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableConfigurationProperties(XxzJobProperties.class)
|
||||||
|
@EnableScheduling
|
||||||
|
public class XxzJobAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public JobExecutor jobExecutor() {
|
||||||
|
return new JobExecutor();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.xiang.core.quartz.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.scheduling.TaskScheduler;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-06 10:20
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class XxzJobTaskScheduleConfig {
|
||||||
|
@Bean
|
||||||
|
public TaskScheduler taskScheduler() {
|
||||||
|
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
|
||||||
|
scheduler.setPoolSize(4);
|
||||||
|
scheduler.setThreadNamePrefix("xxz-job-");
|
||||||
|
scheduler.initialize();
|
||||||
|
return scheduler;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.xiang.core.quartz.executor;
|
||||||
|
|
||||||
|
import com.xiang.core.quartz.model.JobDefinition;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* job任务执行期
|
||||||
|
*
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-06 09:42
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class JobExecutor {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(JobExecutor.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v1版本 本地反射调用
|
||||||
|
* @param jobDefinition
|
||||||
|
*/
|
||||||
|
public void executor(JobDefinition jobDefinition) {
|
||||||
|
try {
|
||||||
|
jobDefinition.getMethod().invoke(jobDefinition.getBean());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("xxz-job execute error, job={}", jobDefinition.getName(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.xiang.core.quartz.holder;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.xiang.core.quartz.model.JobDefinition;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2025-12-30 08:59
|
||||||
|
*/
|
||||||
|
public class JobDefinitionHolder {
|
||||||
|
|
||||||
|
private static final Map<String, JobDefinition> MAP = Maps.newConcurrentMap();
|
||||||
|
|
||||||
|
private JobDefinitionHolder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void register(JobDefinition job) {
|
||||||
|
if (!MAP.containsKey(job.getName())) {
|
||||||
|
MAP.put(job.getName(), job);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<JobDefinition> getAll() {
|
||||||
|
return MAP.values().stream().toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JobDefinition getOne(String name) {
|
||||||
|
return MAP.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateOne(JobDefinition jobDefinition) {
|
||||||
|
if (MAP.containsKey(jobDefinition.getName())) {
|
||||||
|
MAP.put(jobDefinition.getName(), jobDefinition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void delOne(JobDefinition jobDefinition) {
|
||||||
|
MAP.remove(jobDefinition.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package com.xiang.core.quartz.model;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-06 09:30
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class JobDefinition {
|
||||||
|
/**
|
||||||
|
* 应用名称
|
||||||
|
*/
|
||||||
|
private String appName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bean名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* cron
|
||||||
|
*/
|
||||||
|
private String cron;
|
||||||
|
/**
|
||||||
|
* 要执行的方法
|
||||||
|
*/
|
||||||
|
private Method method;
|
||||||
|
/**
|
||||||
|
* spring bean 实例
|
||||||
|
*/
|
||||||
|
private Object bean;
|
||||||
|
/**
|
||||||
|
* 是否支持分布式
|
||||||
|
*/
|
||||||
|
private boolean distributed;
|
||||||
|
/**
|
||||||
|
* 是否启用
|
||||||
|
*/
|
||||||
|
private boolean enabled;
|
||||||
|
/**
|
||||||
|
* 旧cron
|
||||||
|
*/
|
||||||
|
private String oldCron;
|
||||||
|
/**
|
||||||
|
* 上次执行时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime lastRunningTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.xiang.core.quartz.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-06 09:30
|
||||||
|
*/
|
||||||
|
@ConfigurationProperties(prefix = "xxz-job")
|
||||||
|
@Data
|
||||||
|
public class XxzJobProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用名称
|
||||||
|
*/
|
||||||
|
private String appName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DB刷新任务间隔(毫秒)
|
||||||
|
*/
|
||||||
|
private int refreshInterval = 5000;
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package com.xiang.core.quartz.scanner;
|
||||||
|
|
||||||
|
import com.xiang.core.quartz.annotation.XxzJob;
|
||||||
|
import com.xiang.core.quartz.holder.JobDefinitionHolder;
|
||||||
|
import com.xiang.core.quartz.model.JobDefinition;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.aop.support.AopUtils;
|
||||||
|
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-06 09:40
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class JobScanner implements SmartInitializingSingleton {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterSingletonsInstantiated() {
|
||||||
|
|
||||||
|
Map<String, Object> beans =
|
||||||
|
applicationContext.getBeansWithAnnotation(Component.class);
|
||||||
|
|
||||||
|
for (Object bean : beans.values()) {
|
||||||
|
Class<?> targetClass = AopUtils.getTargetClass(bean);
|
||||||
|
ReflectionUtils.doWithMethods(
|
||||||
|
targetClass,
|
||||||
|
method -> registerJob(bean, method),
|
||||||
|
method -> AnnotationUtils.findAnnotation(method, XxzJob.class) != null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void registerJob(Object bean, Method method) {
|
||||||
|
XxzJob xxzJob = AnnotationUtils.findAnnotation(method, XxzJob.class);
|
||||||
|
if (Objects.nonNull(xxzJob)) {
|
||||||
|
JobDefinition job = new JobDefinition();
|
||||||
|
job.setName(xxzJob.name());
|
||||||
|
job.setDistributed(xxzJob.distributed());
|
||||||
|
job.setBean(bean);
|
||||||
|
job.setMethod(method);
|
||||||
|
job.setEnabled(xxzJob.enabled());
|
||||||
|
job.setCron(xxzJob.cron());
|
||||||
|
JobDefinitionHolder.register(job);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.xiang.core.quartz.schedule;
|
||||||
|
|
||||||
|
import com.xiang.core.quartz.executor.JobExecutor;
|
||||||
|
import com.xiang.core.quartz.model.JobDefinition;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.scheduling.TaskScheduler;
|
||||||
|
import org.springframework.scheduling.support.CronTrigger;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-06 09:47
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class JobScheduler {
|
||||||
|
private final TaskScheduler taskScheduler;
|
||||||
|
private final JobExecutor jobExecutor;
|
||||||
|
|
||||||
|
public void schedule(JobDefinition job) {
|
||||||
|
taskScheduler.schedule(
|
||||||
|
() -> jobExecutor.executor(job),
|
||||||
|
new CronTrigger(job.getCron())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||||
|
com.xiang.core.quartz.config.XxzJobAutoConfiguration
|
||||||
34
xservice-quartz-sample/pom.xml
Normal file
34
xservice-quartz-sample/pom.xml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.xiang</groupId>
|
||||||
|
<artifactId>xservice-quartz</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.xiang.starter</groupId>
|
||||||
|
<artifactId>xservice-quartz-sample</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.xiang.starter</groupId>
|
||||||
|
<artifactId>xservice-quartz-core</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.xiang.starter</groupId>
|
||||||
|
<artifactId>xmc-mysql-starter</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
21
xservice-quartz-sample/src/main/java/com/xiang/app/Main.java
Normal file
21
xservice-quartz-sample/src/main/java/com/xiang/app/Main.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package com.xiang.app;
|
||||||
|
|
||||||
|
import com.xiang.core.quartz.annotation.EnableXxzJob;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-06 09:52
|
||||||
|
*/
|
||||||
|
@EnableXxzJob(basePackages = {"com.xiang.app.quartz.sample.springboot.schedule.TestXxzJob1"})
|
||||||
|
@SpringBootApplication
|
||||||
|
@ComponentScan(basePackages = {
|
||||||
|
"com.xiang.*"
|
||||||
|
})
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(Main.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.xiang.app.quartz.sample.springboot.schedule;
|
||||||
|
|
||||||
|
import com.xiang.core.quartz.annotation.XxzJob;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: xiang
|
||||||
|
* @Date: 2026-01-06 09:57
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class TestXxzJob1 {
|
||||||
|
|
||||||
|
@XxzJob(name = "TestXxzJob", cron = "0/1 * * * * ? ", enabled = true)
|
||||||
|
public void test() {
|
||||||
|
log.info("任务调度开始");
|
||||||
|
}
|
||||||
|
}
|
||||||
39
xservice-quartz-sample/src/main/resources/application.yml
Normal file
39
xservice-quartz-sample/src/main/resources/application.yml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
xxz-job:
|
||||||
|
app-name: springboot-quartz-test
|
||||||
|
|
||||||
|
spring:
|
||||||
|
main:
|
||||||
|
allow-bean-definition-overriding: true
|
||||||
|
application:
|
||||||
|
name: springboot-quartz-test
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
group: DEFAULT_GROUP
|
||||||
|
namespace: 00131110-3ecb-4a35-8bbb-624edde1d937
|
||||||
|
server-addr: general.xiangtech.xyz:8848
|
||||||
|
username: nacos
|
||||||
|
password: nacos
|
||||||
|
datasource:
|
||||||
|
dynamic:
|
||||||
|
primary: master
|
||||||
|
datasource:
|
||||||
|
master:
|
||||||
|
url: jdbc:mysql://120.27.153.87:3306/xservice_quartz?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
|
||||||
|
username: quartz
|
||||||
|
password: quartz@123
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
sshConnect: false
|
||||||
|
|
||||||
|
redis:
|
||||||
|
host: r-bp1wt59a6nfyt4e3ltpd.redis.rds.aliyuncs.com
|
||||||
|
port: 6379
|
||||||
|
password: Xiang0000 # 如果无密码可以省略
|
||||||
|
database: 10
|
||||||
|
timeout: 5000
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
max-active: 8
|
||||||
|
max-idle: 8
|
||||||
|
min-idle: 0
|
||||||
|
max-wait: 1000
|
||||||
Reference in New Issue
Block a user