spring framework integration quartz

Keywords: Programming Spring Attribute

spring framework integration quartz

@Scheduled

Spring context support has two annotations for Scheduled tasks under spring, @ enablescheduled and @ Scheduled, which are easy to use

1. Add enableschedule where spring can scan

@SpringBootApplication
@MapperScan("com.hsm.quartztask.mapper")
@EnableScheduling
public class QuartzTaskApplication {
    public static void main(String[] args) {
        SpringApplication.run(QuartzTaskApplication.class, args);
    }
}

2. Write a method, and add @ Scheduled on the method body

@Slf4j
@Component
public class ScheduledDemo {
    @Scheduled(cron = "*/5 * * * * ? ")
    void init() {
        log.info("spring Own simple scheduled tasks");
    }
}

The details of the Scheduled attribute can be found in the following source code

Spring integration quartz

Introduction to quartz

There is no code in the spring boot starter quartz project source code, which can be seen in the pom file

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
</dependency>

Here you can directly use the spring context support project in the spring source code. For details, you can see the files under the org.springframework.scheduling.quartz package of this project

spring uses a lot of factory patterns, and what we have to do is instantiate these bean s. The source code can mainly look at the following files:

  • AdaptableJobFactory this method can add some extensions to JobDateail
  • QuartzJobBean optimizes the Job of quartz, and puts the data in dataMap directly into the attributes of instance task
  • Jobdetailfactorybean JobDetail factory, most of which are also JobDetail properties
  • SimpleTriggerFactoryBean SimpleTrigger factory
  • Crontrigger factorybean crontrigger factory
  • SchedulerFactoryBean scheduler factory

The steps for spring to schedule a scheduled task are similar to those for quartz:

  1. Write task classes that can inherit jobs or quartzjobbeans (quartzjobbeans inherit jobs)
  2. Instantiate JobDetailFactoryBean and bind the task class to it
  3. Instantiate TriggerFactoryBean and bind JobDetail to it
  4. Instantiate the SchedulerFactoryBean and bind the trigger factorybean to it

1. pom file

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

2. Example chemical plant

/**
 * QuartzJobBean The difference with job is that QuartzJobBean puts the datamap data of job directly into the properties of instance object
 */
private String name;

@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
    //TODO invoice query
    log.info("from dataMap Data obtained in:{}", this.getName());
}
@Bean("invoiceQueryJobDetail")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public JobDetailFactoryBean jobDetailFactoryBean() {
    Map<String,Object> dataMap = new HashMap<>();
    dataMap.put("name", "Invoice query");
    JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
    jobDetailFactoryBean.setName("Task name");
    jobDetailFactoryBean.setGroup("Task force");
    jobDetailFactoryBean.setJobClass(InvoiceQueryJobBean.class);
    jobDetailFactoryBean.setJobDataAsMap(dataMap);
    // Must be set to true, if false, the task will be deleted in the scheduler when there is no active trigger associated with it
    jobDetailFactoryBean.setDurability(true);
    return jobDetailFactoryBean;
}

@Autowired
private JobDetailFactoryBean invoiceQueryJobDetail;

@Bean("invoiceQueryTrigger")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public CronTriggerFactoryBean cronTriggerFactoryBean() {
    CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
    cronTriggerFactoryBean.setName("Trigger Name ");
    cronTriggerFactoryBean.setGroup("Trigger group name");
    cronTriggerFactoryBean.setJobDetail(invoiceQueryJobDetail.getObject());
    cronTriggerFactoryBean.setCronExpression("*/5 * * * * ?");
    return cronTriggerFactoryBean;
}

@Autowired
private QuartzJobFactory quartzJobFactory;
@Autowired
private CronTriggerFactoryBean invoiceQueryTrigger;

@Bean
public SchedulerFactoryBean scheduler(){
    SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
    schedulerFactoryBean.setJobFactory(quartzJobFactory);
    schedulerFactoryBean.setTriggers(invoiceQueryTrigger.getObject());
    return schedulerFactoryBean;
}

Factory specific properties can be used by yourself

3. Use Spring Autowire

In order to use only the bean s in the Spring container directly in the Job class, the AdaptableJobFactory factory factory is instantiated here

@Component
public class QuartzJobFactory extends AdaptableJobFactory {
    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;
    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        Object jobInstance = super.createJobInstance(bundle);
        //Here, the properties are injected directly, so you can use the bean s in spring in the job
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}
//Inject the above bean as an attribute of the SchedulerFactoryBean
@Bean
public SchedulerFactoryBean scheduler(){
    SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
    schedulerFactoryBean.setJobFactory(quartzJobFactory);
    schedulerFactoryBean.setTriggers(invoiceQueryTrigger.getObject());
    return schedulerFactoryBean;
}

4. Share a tool class

@Slf4j
public final class QuartzUtils {
    private QuartzUtils() {
    }
    /**
     * @Author: huangsm on 2019/5/28 17:58
     * @param: [cronExpression] 0 0/5 * * * ?
     * @return: boolean
     * @Description: Check whether cron expression is correct
     */
    public static boolean checkCron(String cronExpression){
        return CronExpression.isValidExpression(cronExpression);
    }
    /**
     * @Author: huangsm on 2019/5/28 18:46
     * @param: [cronExpression]
     * @return: void
     * @Description: Print next execution time every five seconds
     */
    public static void printExeTimeWith5Senconds(String cronExpression){
        CronExpression cron ;
        Date now = new Date();
        try {
            cron = new CronExpression(cronExpression);
            //Last execution time
            Date lastDate = now;
            while(true){
                log.info("Execution time:{}", lastDate);
                lastDate = cron.getNextValidTimeAfter(lastDate);

                Thread.sleep(5000L);
            }
        } catch (ParseException e) {
            log.error("cron Expression parsing exception", e);
        }catch (Exception e){
            log.error("Printing cron Expression execution time exception", e);
        }
    }

}

Posted by forcerecon on Thu, 14 May 2020 01:48:38 -0700