In Spring + Spring MVC environment, generally speaking, to achieve timing tasks, we have two solutions, one is to use Spring's own timed task processor @Scheduled annotation, the other is to use the third-party framework Quartz, Spring Boot is derived from Spring + Spring MVC, so it naturally has the timed task implementation strategies in these two Spring, of course, also supports Quartz. In this article, we will look at the implementation of two timing tasks in Spring Boot.
@Scheduled
It is very easy to create a Spring Book project directly with @Scheduled, and add Web dependency spring-boot-starter-web. When the project is created successfully, add the @EnableScheduling annotation to start the timing task:
@SpringBootApplication @EnableScheduling public class ScheduledApplication { public static void main(String[] args) { SpringApplication.run(ScheduledApplication.class, args); } }
Next, configure the timing task:
@Scheduled(fixedRate = 2000) public void fixedRate() { System.out.println("fixedRate>>>"+new Date()); } @Scheduled(fixedDelay = 2000) public void fixedDelay() { System.out.println("fixedDelay>>>"+new Date()); } @Scheduled(initialDelay = 2000,fixedDelay = 2000) public void initialDelay() { System.out.println("initialDelay>>>"+new Date()); }
- First, start a timed task with the @Scheduled annotation.
- Fixed Rate refers to the time interval between task execution, specifically the time interval between the start of two tasks, that is, when the second task begins, the first task may not be finished.
- Fixed Delay represents the time interval between task execution, specifically the time interval between the end of this task and the beginning of the next task.
- Initial Delay indicates the delay time for the first task to start.
- The unit of time is milliseconds.
This is a basic usage. In addition to these basic attributes, the @Scheduled annotation also supports Cron expressions, which can be used to describe the time of a timed task in a very rich way. The cron expression format is as follows:
[seconds] [minutes] [hours] [days] [months] [weeks] [years]
The specific values are as follows:
Serial number | Explain | Is it necessary to fill in? | Values allowed to be filled in | Allowed wildcards |
---|---|---|---|---|
1 | second | yes | 0-59 | - * / |
2 | branch | yes | 0-59 | - * / |
3 | time | yes | 0-23 | - * / |
4 | day | yes | 1-31 | - * ? / L W |
5 | month | yes | 1-12 or JAN-DEC | - * / |
6 | week | yes | 1-7 or SUN-SAT | - * ? / L # |
7 | year | no | 1970-2099 | - * / |
It's important to note that there may be conflicts between dates and weeks in the month, so what's one of the two when you configure it?
Wildcard Meaning:
- Does not specify a value, that is, does not care about the value of a field when used. It should be noted that the dates and weeks in the month may conflict, so what are the two when configuring?
- * Represents all values, such as setting * on a field in seconds, indicating that each second triggers
- To separate multiple values, such as setting "MON,WED,FRI" on the week field to trigger on Monday, Wednesday and Friday
- - Represents an interval, such as setting "10-12" on seconds, indicating that 10, 11, 12 seconds will trigger
- / For incremental triggers, setting "5/15" on seconds means that triggers start at 5 seconds and increase every 15 seconds (5,20,35,50)
- # Number (for the first few weeks of a month), such as setting "6 # 3" on the week field to indicate the third Saturday of a month (Mother's Day and Father's Day are perfect).
- The setting of week field, if using English letters is case-insensitive, that is, MON and mon are the same.
- L means the last word. In the day field setting, it means the last day of the month (according to the current month, if it is February, it will automatically determine whether it is a wet year), and in the week field it means Saturday, which is equivalent to "7" or "SAT" (note that Sunday is the first day). If a number is added before "L", it represents the last of the data. For example, setting a format like "6L" on the week field means "the last Friday of the month".
- W denotes the nearest working day (Monday to Friday) from the specified date, such as setting "15W" on the day field to indicate that the nearest working day to the 15th of each month triggers. If the 15th happens to be a Saturday, then look for the nearest Friday (14) to trigger, if the 15th is a weekend, then look for the nearest Monday (16) to trigger, if the 15th happens to be on the working day (Monday to Friday), then trigger on that day. If the specified format is "1W", it indicates that the latest working day will be triggered from the 1st of each month. If No. 1 is Saturday, it will be triggered next Monday, No. 3. (Note, "W" can only set specific numbers before, not allowed intervals"-)
- L and W can be used together. If "LW" is set on the day field, it means triggering on the last working day of the month (generally referred to as payroll).
For example, in the @Scheduled annotation, a simple cron expression is triggered every five seconds, as follows:
@Scheduled(cron = "0/5 * * * * *") public void cron() { System.out.println(new Date()); }
The above is about using the @Scheduled annotation to achieve the timing task. Next, let's look at how to use Quartz to achieve the timing task.
Quartz
Usually in projects, unless the business involved in the timing task is too simple and the @Scheduled annotation is used to solve the timing task, most of the cases may be using Quartz to do the timing task. To use Quartz in Spring Boot, you just need to add Quartz dependencies when creating a project:
After the project is created, annotations to open timed tasks are also needed:
@SpringBootApplication @EnableScheduling public class QuartzApplication { public static void main(String[] args) { SpringApplication.run(QuartzApplication.class, args); } }
In the process of using Quartz, there are two key concepts, one is JobDetail (what to do) and the other is trigger (when to do). To define JobDetail, we need to define Job first. There are two ways to define Job:
The first way is to define a Bean directly:
@Component public class MyJob1 { public void sayHello() { System.out.println("MyJob1>>>"+new Date()); } }
There are two points about this way of definition:
- First, register the Job in the Spring container.
- One drawback of this definition is that it cannot be passed on.
The second way of definition is to inherit QuartzJobBean and implement the default method:
public class MyJob2 extends QuartzJobBean { HelloService helloService; public HelloService getHelloService() { return helloService; } public void setHelloService(HelloService helloService) { this.helloService = helloService; } @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { helloService.sayHello(); } } public class HelloService { public void sayHello() { System.out.println("hello service >>>"+new Date()); } }
Compared with the first method, this method supports parameterization, and the executeInternal method will be executed when the task starts.
Once Job has it, create the class and configure the JobDetail and Trigger triggers as follows:
@Configuration public class QuartzConfig { @Bean MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean() { MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean(); bean.setTargetBeanName("myJob1"); bean.setTargetMethod("sayHello"); return bean; } @Bean JobDetailFactoryBean jobDetailFactoryBean() { JobDetailFactoryBean bean = new JobDetailFactoryBean(); bean.setJobClass(MyJob2.class); JobDataMap map = new JobDataMap(); map.put("helloService", helloService()); bean.setJobDataMap(map); return bean; } @Bean SimpleTriggerFactoryBean simpleTriggerFactoryBean() { SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean(); bean.setStartTime(new Date()); bean.setRepeatCount(5); bean.setJobDetail(methodInvokingJobDetailFactoryBean().getObject()); bean.setRepeatInterval(3000); return bean; } @Bean CronTriggerFactoryBean cronTrigger() { CronTriggerFactoryBean bean = new CronTriggerFactoryBean(); bean.setCronExpression("0/10 * * * * ?"); bean.setJobDetail(jobDetailFactoryBean().getObject()); return bean; } @Bean SchedulerFactoryBean schedulerFactoryBean() { SchedulerFactoryBean bean = new SchedulerFactoryBean(); bean.setTriggers(cronTrigger().getObject(), simpleTriggerFactoryBean().getObject()); return bean; } @Bean HelloService helloService() { return new HelloService(); } }
For this configuration, the following points are mentioned:
- JobDetail is configured in two ways: Method Invoking JobDetailFactoryBean and JobDetailFactoryBean.
- Using MethodInvoking JobDetailFactoryBean, you can configure the name of the target Bean and the name of the target method, which does not support passing parameters.
- JobDetail can be configured with JobDetail FactoryBean, and task class inherits from QuartzJobBean, which supports parameter transfer and encapsulates parameters for transfer in JobDataMap.
- Trigger is a trigger. Quartz defines several triggers. Here we show you two of them, Simple Trigger and Ron Trigger.
- SimpleTrigger is somewhat similar to the basic usage of @Scheduled mentioned earlier.
- CronTrigger is somewhat similar to the use of cron expressions in @Scheduled.
Once the definitions are complete, you can see the execution of the timed tasks by launching the Spring Book project.
summary
Here we mainly show you how to integrate the two timing tasks in Spring Boot. After successful integration, the remaining usage is basically consistent with SSM usage, no more details.
Pay attention to the public number boy, focus on Spring Boot + micro services, share regular video tutorials, pay attention to Java, get the Java dry goods Matsumoto carefully prepared for you! ___________