Preface
The timing task function is implemented in Spring Boot. You can use the timing task scheduling that comes with Spring, or you can use the integrated classic open source component Quartz to achieve task scheduling.
This article will introduce in detail the relevant content on the implementation of timed tasks in Spring Boot, and share it for your reference and learning. I won’t say much below, let’s take a look at the detailed introduction together.
1. Spring timer
1. Cron expression method
Using the built-in timing tasks is very simple. You just need to add annotations like the following and do not need to inherit any timing processing interface like the ordinary timing task framework. The simple example code is as follows:
package com.power.demo.scheduledtask.simple;import com.power.demo.util.DateTimeUtil;import org.springframework.scheduling.annotation.EnableScheduling;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Component;import java.util.Date;@Component@EnableSchedulingpublic class SpringTaskA { /** * CRON expression reference: http://cron.qqe2.com/ **/ @Scheduled(cron = "*/5 * * * * ?", zone = "GMT+8:00") private void timerCron() { try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } System.out.println(String.format("(timerCron)%s Execute every 5 seconds, logging", DateTimeUtil.fmtDate(new Date()))); }}SpringTaskAIn the above code, add @EnableScheduling annotation to a class, add @Scheduled to the method, configure the cron expression, and the simplest cron timing task is completed. The following are the components of the cron expression:
@Scheduled(cron = "[Seconds] [Minutes] [Hours] [Day of month] [Month] [Day of week] [Year]")
2. fixedRate and fixedDelay
The @Scheduled annotation eliminates the cron expression, and there are other configuration methods, such as fixedRate and fixedDelay. The following example implements different forms of timing task scheduling through different configuration methods. The example code is as follows:
package com.power.demo.scheduledtask.simple;import com.power.demo.util.DateTimeUtil;import org.springframework.scheduling.annotation.EnableScheduling;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Component;import java.util.Date;@Component@EnableSchedulingpublic class SpringTaskB { /*fixedRate:Execute again 5 seconds after the last time point*/ @Scheduled(fixedRate = 5000) public void timerFixedRate() { try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } System.out.println(String.format("(fixedRate)Current time: %s", DateTimeUtil.fmtDate(new Date()))); } /*fixedDelay: Execute 5 seconds after the last execution time point*/ @Scheduled(fixedDelay = 5000) public void timerFixedDelay() { try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } System.out.println(String.format("(fixedDelay)Current time: %s", DateTimeUtil.fmtDate(new Date()))); } /*Execute after the first delay is 2 seconds, and then execute it every 5 seconds according to the fixedDelay rule*/ @Scheduled(initialDelay = 2000, fixedDelay = 5000) public void timerInitDelay() { try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } System.out.println(String.format("(initDelay)Current time: %s", DateTimeUtil.fmtDate(new Date()))); }}SpringTaskBNote the main differences:
@Scheduled(fixedRate = 5000) : Execute again 5 seconds after the last time point of execution
@Scheduled(fixedDelay = 5000) : Execute again 5 seconds after the last execution time point
@Scheduled(initialDelay=2000, fixedDelay=5000) : Execute after the first delay is 2 seconds, and then press the fixedDelay rule to execute every 5 seconds
Sometimes, many projects need to be configured and executed immediately after the scheduled tasks are configured, and initialDelay is not required.
3. zone
@Scheduled annotation also has a familiar attribute zone, indicating the time zone. Usually, if not written, the timing task will use the server's default time zone; if your task wants to run at a specific time zone and a specific time point, for example, a common multilingual system may run scripts to update data regularly, you can set a time zone, such as East Eighth Zone, which can be set to:
zone = "GMT+8:00"
2. Quartz
Quartz is one of the most widely used open source task scheduling frameworks, and many companies implement their own timing task management systems based on it. Quartz provides two most commonly used timing task triggers, namely SimpleTrigger and CronTrigger. This article takes the most widely used CronTrigger as an example.
1. Add dependencies
<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.0</version> </dependency>
2. Configure cron expressions
As required for the sample code, add the following configuration to the application.properties file:
## Quartz timed job configuration job.taska.cron=*/3 * * * * ?job.taskb.cron=*/7 * * * * ?job.taskmail.cron=*/5 * * * * ?job.taskmail.cron=*/5 * * * ?
In fact, we can write it in the code or persist it in the DB and then read it without configuring it.
3. Add timed tasks to implement
Task 1:
package com.power.demo.scheduledtask.quartz;import com.power.demo.util.DateTimeUtil;import org.quartz.DisallowConcurrentExecution;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import java.util.Date;@DisallowConcurrentExecutionpublic class QuartzTaskA implements Job { @Override public void execute(JobExecutionContext var1) throws JobExecutionException { try { Thread.sleep(1); } catch (Exception e) { e.printStackTrace(); } System.out.println(String.format("(QuartzTaskA)%s Execute every 3 seconds, log log", DateTimeUtil.fmtDate(new Date()))); }}QuartzTaskATask 2:
package com.power.demo.scheduledtask.quartz;import com.power.demo.util.DateTimeUtil;import org.quartz.DisallowConcurrentExecution;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import java.util.Date;@DisallowConcurrentExecutionpublic class QuartzTaskB implements Job { @Override public void execute(JobExecutionContext var1) throws JobExecutionException { try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } System.out.println(String.format("(QuartzTaskB)%s Execute every 7 seconds, log log", DateTimeUtil.fmtDate(new Date()))); }}QuartzTaskBTimely send email tasks:
package com.power.demo.scheduledtask.quartz;import com.power.demo.service.contract.MailService;import com.power.demo.util.DateTimeUtil;import com.power.demo.util.PowerLogger;import org.joda.time.DateTime;import org.quartz.DisallowConcurrentExecution;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.springframework.beans.factory.annotation.Autowired;import java.util.Date;@DisallowConcurrentExecutionpublic class MailSendTask implements Job { @Autowired private MailService mailService; @Override public void execute(JobExecutionContext var1) throws JobExecutionException { System.out.println(String.format("(MailSendTask)%s Send mail every 5 seconds", DateTimeUtil.fmtDate(new Date()))); try { //Thread.sleep(1); DateTime dtNow = new DateTime(new Date()); Date startTime = dtNow.minusMonths(1).toDate();//A month ago Date endTime = dtNow.plusDays(1).toDate(); mailService.autoSend(startTime, endTime); PowerLogger.info(String.format("Send mail, start time: %s, end time: %s", DateTimeUtil.fmtDate(startTime), DateTimeUtil.fmtDate(endTime))); } catch (Exception e) { e.printStackTrace(); PowerLogger.info(String.format("Send mail, exception occurs: %s, end time: %s", e)); } }}MailSendTaskImplementing tasks looks very simple, just inherit Quartz's Job interface and rewrite the execute method.
4. Integrate Quartz timing tasks
How to make Spring automatically recognize the initialization of Quartz timing task instances? This requires referring to Spring managed beans, exposing the necessary beans to Spring containers, and automatically injecting them by defining Job Factory.
First, add the Spring Injected Job Factory class:
package com.power.demo.scheduledtask.quartz.config;import org.quartz.spi.TriggerFiredBundle;import org.springframework.beans.factory.config.AutowireCapableBeanFactory;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.scheduling.quartz.SpringBeanJobFactory;public final class AutowireBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware { private transient AutowireCapableBeanFactory beanFactory; /** * Spring provides a mechanism that allows you to obtain ApplicationContext, that is, ApplicationContextAware interface* For a class that implements the ApplicationContextAware interface, Spring will instantiate it and call its * public voidsetApplicationContext(ApplicationContext applicationContext) throws BeansException; interface, * Pass the context to which the bean belongs. **/ @Override public void setApplicationContext(final ApplicationContext context) { beanFactory = context.getAutowireCapableBeanFactory(); } @Override protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception { final Object job = super.createJobInstance(bundle); beanFactory.autowireBean(job); return job; }}AutowireBeanJobFactoryDefine QuartzConfig:
package com.power.demo.scheduledtask.quartz.config;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.quartz.CronTriggerFactoryBean;import org.springframework.scheduling.quartz.SchedulerFactoryBean;@Configurationpublic class QuartzConfig { @Autowired @Qualifier("quartzTaskATrigger") private CronTriggerFactoryBean quartzTaskATrigger; @Autowired @Qualifier("quartzTaskBTrigger") private CronTriggerFactoryBean quartzTaskBTrigger; @Autowired @Qualifier("mailSendTrigger") private CronTriggerFactoryBean mailSendTrigger; //The job in Quartz automatically injects the object hosted by the spring container @Bean public AutowireBeanJobFactory autoWiringSpringBeanJobFactory() { return new AutowireBeanJobFactory(); } @Bean public SchedulerFactoryBean schedulerFactoryBean() { SchedulerFactoryBean scheduler = new SchedulerFactoryBean(); scheduler.setJobFactory(autoWiringSpringBeanJobFactory()); //Configure the Job class injected by Spring//Set CronTriggerFactoryBean and set the task Trigger scheduler.setTriggers( quartzTaskATrigger.getObject(), quartzTaskBTrigger.getObject(), mailSendTrigger.getObject() ); return scheduler; }}QuartzConfigNext, configure the job details:
package com.power.demo.scheduledtask.quartz.config;import com.power.demo.util.ConfigUtil;import com.power.demo.scheduledtask.quartz.MailSendTask;import com.power.demo.scheduledtask.quartz.QuartzTaskA;import com.power.demo.scheduledtask.quartz.QuartzTaskB;import com.power.demo.util.ConfigUtil;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.quartz.CronTriggerFactoryBean;import org.springframework.scheduling.quartz.JobDetailFactoryBean;@Configurationpublic class TaskSetting { @Bean(name = "quartzTaskA") public JobDetailFactoryBean jobDetailAFactoryBean() { //Generate JobDetail JobDetailFactoryBean factory = new JobDetailFactoryBean(); factory.setJobClass(QuartzTaskA.class); //Set the corresponding Job factory.setGroup("quartzTaskGroup"); factory.setName("quartzTaskAJob"); factory.setDurability(false); factory.setDescription("test task A"); return factory; } @Bean(name = "quartzTaskATrigger") public CronTriggerFactoryBean cronTriggerAFactoryBean() { String cron = ConfigUtil.getConfigVal(AppField.JOB_TASKA_CRON); CronTriggerFactoryBean stFactory = new CronTriggerFactoryBean(); //Set JobDetail stFactory.setJobDetail(jobDetailAFactoryBean().getObject()); stFactory.setStartDelay(1000); stFactory.setName("quartzTaskATrigger"); stFactory.setGroup("quartzTaskGroup"); stFactory.setCronExpression(cron); return stFactory; } @Bean(name = "quartzTaskB") public JobDetailFactoryBean jobDetailBFactoryBean() { // Generate JobDetail JobDetailFactoryBean factory = new JobDetailFactoryBean(); factory.setJobClass(QuartzTaskB.class); // Set the corresponding Job factory.setGroup("quartzTaskGroup"); factory.setName("quartzTaskBJob"); factory.setDurability(false); factory.setDescription("Test Task B"); return factory; } @Bean(name = "quartzTaskBTrigger") public CronTriggerFactoryBean cronTriggerBFactoryBean() { String cron = ConfigUtil.getConfigVal(AppField.JOB_TASKB_CRON); CronTriggerFactoryBean stFactory = new CronTriggerFactoryBean(); //Set JobDetail stFactory.setJobDetail(jobDetailBFactoryBean().getObject()); stFactory.setStartDelay(1000); stFactory.setName("quartzTaskBTrigger"); stFactory.setGroup("quartzTaskGroup"); stFactory.setCronExpression(cron); return stFactory; } @Bean(name = "mailSendTask") public JobDetailFactoryBean jobDetailMailFactoryBean() { // Generate JobDetail JobDetailFactoryBean factory = new JobDetailFactoryBean(); factory.setJobClass(MailSendTask.class); //Set the corresponding Job factory.setGroup("quartzTaskGroup"); factory.setName("mailSendTaskJob"); factory.setDurability(false); factory.setDescription("MailsendTrigger"); return factory; } @Bean(name = "mailSendTrigger") public CronTriggerFactoryBean cronTriggerMailFactoryBean() { String cron = ConfigUtil.getConfigVal(AppField.JOB_TASKMAIL_CRON); CronTriggerFactoryBean stFactory = new CronTriggerFactoryBean(); //Set JobDetail stFactory.setJobDetail(jobDetailMailFactoryBean().getObject()); stFactory.setStartDelay(1000); stFactory.setName("mailSendTrigger"); stFactory.setGroup("quartzTaskGroup"); stFactory.setCronExpression(cron); return stFactory; }}TaskSettingFinally, start your Spring Boot timing task application, and a complete timing task based on Quartz schedule will be implemented.
In this timed task example, there is a timed mail send task MailSendTask. The next article will share the simple mail system in Spring Boot application using MongoDB as the storage medium.
Extended reading:
Many companies have their own timed task scheduling framework and systems. How to integrate the Quartz cluster in Spring Boot to implement dynamic timed task configuration?
refer to:
//www.VeVB.COM/article/139591.htm
//www.VeVB.COM/article/139597.htm
Summarize
The above is the entire content of this article. I hope that the content of this article has certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support to Wulin.com.