我能否在Java中使用Quartz只运行一次任务?我知道在这种情况下使用Quartz没有意义。但问题是,我有多个作业需要执行多次,所以我正在使用Quartz。
这个可能吗?
我能否在Java中使用Quartz只运行一次任务?我知道在这种情况下使用Quartz没有意义。但问题是,我有多个作业需要执行多次,所以我正在使用Quartz。
这个可能吗?
你应该使用SimpleTrigger,它会在特定时间触发且不会重复。TriggerUtils有许多方便的方法可以创建这些类型的触发器。
可以的!
JobKey jobKey = new JobKey("testJob");
JobDetail job = newJob(TestJob.class)
.withIdentity(jobKey)
.storeDurably()
.build();
scheduler.addJob(job, true);
scheduler.triggerJob(jobKey); //trigger a job inmediately
@Override
protected void execute(JobExecutionContext context)
throws JobExecutionException {
...
// process execution
...
context.getScheduler().unscheduleJob(triggerKey);
...
}
其中triggerKey是仅运行一次的作业的ID。之后,该作业将不再被调用。
以下是如何使用Quartz 2.x立即运行TestJob
类的示例:
public JobKey runJob(String jobName)
{
// if you don't call startAt() then the current time (immediately) is assumed.
Trigger runOnceTrigger = TriggerBuilder.newTrigger().build();
JobKey jobKey = new JobKey(jobName);
JobDetail job = JobBuilder.newJob(TestJob.class).withIdentity(jobKey).build();
scheduler.scheduleJob(job, runOnceTrigger);
return jobKey;
}
使用以下文章中的一些想法:
我成功地拼凑出了一个工作实现,使我能够执行以下操作:
我想到了以下CommandLineRunner类:
public class BatchCommandLineRunner implements CommandLineRunner {
@Autowired
private Scheduler scheduler;
private static final Logger LOGGER = LoggerFactory.getLogger(BatchCommandLineRunner.class);
public void run(final String... args) throws SchedulerException {
LOGGER.info("BatchCommandLineRunner: running with args -> " + Arrays.toString(args));
for (final String jobName : args) {
final JobKey jobKey = findJobKey(jobName);
if (jobKey != null) {
LOGGER.info("Triggering job for: " + jobName);
scheduler.triggerJob(jobKey);
} else {
LOGGER.info("No job found for jobName: " + jobName);
}
}
}
private JobKey findJobKey(final String jobNameToFind) throws SchedulerException {
for (final JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals("DEFAULT"))) {
final String jobName = jobKey.getName();
if (jobName.equals(jobNameToFind)) {
return jobKey;
}
}
return null;
}
}
@Configuration
public class BatchConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(BatchConfiguration.class);
@Bean
public BatchCommandLineRunner batchCommandLineRunner() {
return new BatchCommandLineRunner();
}
@Bean
public CommandLineRunner runCommandLineArgs(final ApplicationArguments applicationArguments) throws Exception {
final List<String> jobNames = applicationArguments.getOptionValues("jobName");
LOGGER.info("runCommandLineArgs: running the following jobs -> " + ArrayUtils.toString(jobNames));
batchCommandLineRunner().run(jobNames.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
return null;
}
}
java -jar <your_application>.jar --jobName=<QuartzRegisteredJobDetailFactoryBean>
scheduler.setJobDetails(...)
)
- 除缺少scheduler.setTriggers(...)
调用外,一切都与CronTriggerFactoryBean的作业基本相同
- Spring知道在应用程序启动后执行CommandLineRunner类
- 我将传递到应用程序中的参数硬编码为“jobName”
- 我假定所有作业的组名为“DEFAULT”;如果您想使用不同的组,则在获取用于实际运行作业的JobKey时需要进行调整
- 没有任何内容可以防止通过CLI多次运行此作业,但是它使用SimpleTrigger方法在每次应用程序加载时触发,因此对我来说更好;如果这不可接受,可能使用StepListener和ExitStatus等可以防止它被执行两次。我不确定Mono和Java中的Quartz有多相似,但这似乎在.Net中可以工作。
TriggerBuilder.Create ()
.StartNow ()
.Build ();
now()
。 - jmizv.withRepeatCount(0)
。public final int TEN_SECONDS = 10;
Trigger trigger = newTrigger()
.withIdentity("myJob", "myJobGroup")
.startAt(new Date(System.currentMillis()+TEN_SECONDS*1000)
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withRepeatCount(0)
.withIntervalInMinutes(1))
.build();