gpt4 book ai didi

java - 在数据库中保留 Quartz 触发器的正确​​方法

转载 作者:搜寻专家 更新时间:2023-11-01 01:03:53 25 4
gpt4 key购买 nike

我是 Quartz 的新手,现在我需要在 Spring Web 应用程序中安排一些作业。

我知道 Spring + Quartz 集成(我使用的是 Spring v 3.1.1),但我想知道这是否是正确的方法。

特别是我需要在数据库中保留我的计划任务,这样我就可以在应用程序重新启动时重新初始化它们。

Spring 调度包装器是否提供了一些实用程序来执行此操作?你能建议我遵循一些“众所周知”的方法吗?

最佳答案

这是我处理这种情况的一种方法。

首先在我的 Spring 配置中我指定了一个 SchedulerFactoryBean我可以从中注入(inject) Scheduler进入其他 bean 类。

<bean name="SchedulerFactory"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="applicationContextSchedulerContextKey">
<value>applicationContext</value>
</property>
</bean>

然后,当我在我的应用程序中创建一个作业时,我将作业的详细信息存储在数据库中。此服务由我的一个 Controller 调用并安排作业:

@Component
public class FollowJobService {

@Autowired
private FollowJobRepository followJobRepository;

@Autowired
Scheduler scheduler;

@Autowired
ListableBeanFactory beanFactory;

@Autowired
JobSchedulerLocator locator;

public FollowJob findByClient(Client client){
return followJobRepository.findByClient(client);
}

public void saveAndSchedule(FollowJob job) {
job.setJobType(JobType.FOLLOW_JOB);
job.setCreatedDt(new Date());
job.setIsEnabled(true);
job.setIsCompleted(false);

JobContext context = new JobContext(beanFactory, scheduler, locator, job);
job.setQuartzGroup(context.getQuartzGroup());
job.setQuartzName(context.getQuartzName());

followJobRepository.save(job);

JobSchedulerUtil.schedule(new JobContext(beanFactory, scheduler, locator, job));
}
}

JobContext我构建包含有关作业的详细信息,并最终传递给用于调度作业的实用程序。这是实际安排作业的实用程序方法的代码。请注意,在我的服务中,我自动连接了 JobScheduler并将其传递给 JobContext .另请注意,我使用存储库将作业存储在数据库中。

/**
* Schedules a DATA_MINING_JOB for the client. The job will attempt to enter
* followers of the target into the database.
*/
@Override
public void schedule(JobContext context) {
Client client = context.getNetworkSociallyJob().getClient();
this.logScheduleAttempt(context, client);

JobDetail jobDetails = JobBuilder.newJob(this.getJobClass()).withIdentity(context.getQuartzName(), context.getQuartzGroup()).build();
jobDetails.getJobDataMap().put("job", context.getNetworkSociallyJob());
jobDetails.getJobDataMap().put("repositories", context.getRepositories());

Trigger trigger = TriggerBuilder.newTrigger().withIdentity(context.getQuartzName() + "-trigger", context.getQuartzGroup())
.withSchedule(cronSchedule(this.getSchedule())).build();

try {
context.getScheduler().scheduleJob(jobDetails, trigger);
this.logSuccess(context, client);

} catch (SchedulerException e) {
this.logFailure(context, client);
e.printStackTrace();
}
}

所以在所有这些代码执行之后,我发生了两件事,我的作业存储在数据库中,并且使用 quartz 调度程序对其进行了调度。现在,如果应用程序重新启动,我想使用调度程序重新安排我的作业。为此,我注册了一个实现 ApplicationListener<ContextRefreshedEvent> 的 bean。每次容器重新启动或启动时由 Spring 调用。

<bean id="jobInitializer" class="com.network.socially.web.jobs.JobInitializer"/>

JobInitializer.class

public class JobInitializer implements ApplicationListener<ContextRefreshedEvent> {

Logger logger = LoggerFactory.getLogger(JobInitializer.class);

@Autowired
DataMiningJobRepository repository;

@Autowired
ApplicationJobRepository jobRepository;

@Autowired
Scheduler scheduler;

@Autowired
JobSchedulerLocator locator;

@Autowired
ListableBeanFactory beanFactory;

@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
logger.info("Job Initilizer started.");

//TODO: Modify this call to only pull completed & enabled jobs
for (ApplicationJob applicationJob : jobRepository.findAll()) {
if (applicationJob.getIsEnabled() && (applicationJob.getIsCompleted() == null || !applicationJob.getIsCompleted())) {
JobSchedulerUtil.schedule(new JobContext(beanFactory, scheduler, locator, applicationJob));
}
}
}

}

此类 Autowiring 调度程序和一个存储库,该存储库获取我实现 ApplicationJob 的每个作业的实例。界面。使用来自这些数据库记录的信息,我可以使用我的调度程序实用程序来重建我的作业。

所以基本上我手动将作业存储在我的数据库中并通过注入(inject) Scheduler 的实例手动安排它们在适当的 bean 里。要重新安排它们,我查询我的数据库,然后使用 ApplicationListener 安排它们考虑到容器的重启和启动。

关于java - 在数据库中保留 Quartz 触发器的正确​​方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17402112/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com