The right way to save quartz triggers in a database

I'm new to Quartz, and now I need to schedule some tasks in the Spring web application.

I know about Spring + quartz integration (I'm using Spring v 3.1.1), but I'm wondering if this is the right way to follow.

In particular, I need to save my scheduled tasks in the database so that I can reinitialize them when the application restarts.

Are there some utilities provided by the Spring Planning Shell for this? Can you offer me a "well-known" approach?

+4
source share
2 answers

Here is one way to handle this scenario.

First, in my Spring configuration, I specify a SchedulerFactoryBean from which I can inject the Scheduler into other beans.

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

Then, when I create the task in my application, I save the details of the task in the database. This service is called by one of my controllers, and it assigns a task:

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

The JobContext line I contains detailed information about the job and is ultimately passed to the task scheduling utility. Here is the code for a utility method that actually plans to work. Please note that in my service I scroll through the JobScheduler and pass it to the JobContext . Also note that I am storing the job in the database using my repository.

 /** * 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(); } } 

So, after doing all this code, I did two things: my work is stored in a database and scheduled using a quartz scheduler. Now, if the application restarts, I want to reschedule my tasks using the scheduler. To do this, I will register a bean that implements the ApplicationListener<ContextRefreshedEvent> , which is called by Spring each time the container is restarted or launched.

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

This class auto-installs the scheduler and repository, which grabs instances of each of my jobs implementing the ApplicationJob interface. Using the information from these database entries, I can use my scheduler utility to restore my jobs.

So, basically I manually store tasks in my database and manually schedule them by inserting an instance of Scheduler into the appropriate beans. To migrate them, I query my database and then plan them using ApplicationListener to account for the restart and launch of the container.

+12
source

I assume that there is enough documentation for the Spring and Quartz JDBC job repositories; eg:

+5
source

Source: https://habr.com/ru/post/1489068/


All Articles