Quartz
该扩展组件支持通过用户界面管理 Quartz 任务:
-
使用已有的
org.quartz.Job
接口实现创建新的 Quartz 任务。 -
暂停和继续执行任务。
-
触发非活动任务的立即执行。
-
编辑任务触发器和参数。
-
删除任务。
安装
按照 扩展组件 章节的说明进行安装。
手动安装,需在 build.gradle
文件添加下列依赖:
implementation 'io.jmix.quartz:jmix-quartz-starter'
implementation 'io.jmix.quartz:jmix-quartz-ui-starter'
使用
按照下列步骤创建并设定任务计划:
-
创建一个类,实现
org.quartz.Job
接口。调度器会执行其execute()
方法。示例:package quartz.ex1.app; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SampleJob implements Job { private static final Logger log = LoggerFactory.getLogger(SampleJob.class); @Override public void execute(JobExecutionContext context) throws JobExecutionException { log.info("Sample job is executed"); } }
在任务类中,可以用
@Autowired
注入 Spring bean。 -
启动应用程序,打开 Administration(管理) → Quartz jobs(Quartz 任务) 界面,并点击 Create(新建)。
-
在 Name(名称) 字段输入一个唯一的名称,并在 Class(类) 字段选择任务类。
Group(分组) 字段是可选的,用于在 UI 中对任务进行分组。
-
在 Triggers(触发器) 标签页为任务创建至少一个触发器。可以选择 Cron expression(Cron 表达式) 或 Simple(简易) 调度类型。前一种方式需要输入一个 Cron 表达式,例如,
0/5 * * ? * * *
(每一个第五秒)。后一种方式仅需输入任务执行的重复周期(单位为毫秒)。
保存触发器和任务之后,会根据触发器的设置立即开始调度。
如需修改任务设置,首先选中任务并点击 Pause(暂停)。保存修改后,可以点击 Resume(继续) 继续任务调度。
也可以点击 Execute now(马上执行) 按钮开始执行任一注册的任务,即便任务此时还没有触发器。该功能方便测试。
-
任务中的认证
调度器执行的代码未经认证,即未与任何用户关联。
如需调用需要认证的操作,例如,通过 DataManager
处理数据,可以使用 SystemAuthenticator 或 @Authenticated
注解:
public class SampleAuthenticatedJob implements Job {
private static final Logger log = LoggerFactory.getLogger(SampleAuthenticatedJob.class);
@Autowired
private DataManager dataManager;
@Authenticated
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
int usersCount = dataManager.load(User.class).all().list().size();
log.info("There are {} registered users", usersCount);
}
}
还可以使用 UnconstrainedDataManager 在未认证的上下文中处理数据。
|
任务参数
在 Job editor(任务编辑器) 界面的 Job data parameters(任务数据参数) 标签页可以为任务实例设置参数。可以像下面这样在任务类中使用参数:
public class SampleParameterizedJob implements Job {
private static final Logger log = LoggerFactory.getLogger(SampleParameterizedJob.class);
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
String paramStr = jobDataMap.entrySet().stream()
.map(e -> e.getKey() + " : " + e.getValue())
.collect(Collectors.joining(", ", "[", "]"));
log.info("Sample job is executed with parameters: " + paramStr);
}
}
跟踪任务执行
如需跟踪任务的执行,创建一个 bean,实现 JobListener
接口,或继承 JobListenerSupport
:
package quartz.ex1.app;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.listeners.JobListenerSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class JobExecutionListener extends JobListenerSupport {
private static final Logger log = LoggerFactory.getLogger(JobExecutionListener.class);
@Autowired
private Scheduler scheduler;
@Override
public String getName() {
return "SampleJobExecutionListener";
}
@PostConstruct
private void registerListener() { (1)
try {
scheduler.getListenerManager().addJobListener(this);
} catch (SchedulerException e) {
log.error("Cannot register job listener", e);
}
}
@Override
public void jobWasExecuted(JobExecutionContext context,
JobExecutionException jobException) { (2)
log.info("jobWasExecuted: name={}, context={}",
context.getJobDetail().getKey().getName(), context);
}
}
1 | bean 初始化完成后由 Spring 调用。 |
2 | 任务执行完成后,由 Quartz 调度器调用。 |
在 jobWasExecuted()
方法内,可以将任务的执行结果保存至日志或者数据库。