在数据库中持久保存Quartz触发器的正确​​方法

dav*_*ooh 5 java spring persistence jdbc quartz-scheduler

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

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

特别是我需要将我的计划任务保存在数据库中,以便在重新启动应用程序时重新初始化它们.

Spring调度包装器是否提供了一些实用程序来执行此操作?你能告诉我一些"众所周知"的方法吗?

Kev*_*sox 13

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

首先在我的Spring配置中指定一个SchedulerFactoryBean我可以从中注入Scheduler其他bean的.

<bean name="SchedulerFactory"
    class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="applicationContextSchedulerContextKey">
        <value>applicationContext</value>
    </property>
</bean>
Run Code Online (Sandbox Code Playgroud)

然后,当我在应用程序中创建作业时,我将作业的详细信息存储在数据库中.这个服务由我的一个控制器调用,它安排工作:

@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));
    }
}
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

<bean id="jobInitializer" class="com.network.socially.web.jobs.JobInitializer"/>
Run Code Online (Sandbox Code Playgroud)

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));
            }
        }       
    }

}
Run Code Online (Sandbox Code Playgroud)

此类自动装配调度程序和存储库,该存储库用于获取实现该ApplicationJob接口的每个作业的实例.使用这些数据库记录中的信息,我可以使用我的调度程序实用程序来重建我的作业.

所以基本上我手动将作业存储在我的数据库中,并通过注入Scheduler适当bean 的实例来手动调度它们.要重新安排它们,我查询我的数据库,然后使用ApplicationListenerto帐户安排它们重新启动和启动容器.


nob*_*beh 7

我想有一些文档可用于Spring和Quartz JDBC作业存储集成; 例如: