Preface
In our daily development, many times, timed tasks are not written dead, but written to the database, so as to achieve the dynamic configuration of scheduled tasks, the following is a simple example to achieve this function.
First, create a new Springboot project, and add dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency><!--For testing purposes, the memory database is used here-<groupId>com.h2database</groupId> <art ifactid>h2</artifactid> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <ARTIFACTID>SPRING-BOOT-STARTER-TEST</ARTIFAC tid> <scope>test</scope> </dependency> <dependency> <groupid>org.quar Tz-scheduler</groupid> <artifactId>quartz</artifactId> <version>2.2.1</version> ; <exclusions> <exclusion> <artifactId>slf4j-api</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency> ; <dependency><!--This dependency must be added with sping support for schedule-<groupid>org.springframework</group Id> <artifactId>spring-context-support</artifactId> </dependency>
Second, the configuration file application.properties
#服务器端口号
server.port=7902
#是否生成ddl语句
Spring.jpa.generate-ddl=false
#是否打印sql语句
Spring.jpa.show-sql=true
#自动生成ddl, set to none here because specific DDL is specified
Spring.jpa.hibernate.ddl-auto=none
#使用H2数据库
Spring.datasource.platform=h2
#指定生成数据库的schema文件位置
Spring.datasource.schema=classpath:schema.sql
#指定插入数据库语句的脚本位置
Spring.datasource.data=classpath:data.sql
#配置日志打印信息
Logging.level.root=info
Logging.level.org.hibernate=info
Logging.level.org.hibernate.type.descriptor.sql.basicbinder=trace
Logging.level.org.hibernate.type.descriptor.sql.basicextractor=trace
Logging.level.com.itmuch=debug
III. entity Category
Package com.chhliu.springboot.quartz.entity;
Import Javax.persistence.Column;
Import javax.persistence.Entity;
Import Javax.persistence.GeneratedValue;
Import Javax.persistence.GenerationType;
Import Javax.persistence.Id;
@Entity
public class Config {br/> @Id
Private Long ID;
@Column private String cron;/** * @return the id */public Long getId() { return id;} ……此处省略getter和setter方法……
}
Iv. Task category
Package com.chhliu.springboot.quartz.entity;
Import Org.slf4j.Logger;
Import Org.slf4j.LoggerFactory;
Import org.springframework.context.annotation.Configuration;
Import org.springframework.scheduling.annotation.EnableScheduling;
Import org.springframework.stereotype.Component;
@Configuration
@Component//This note must be added
@EnableScheduling//This note must be added
public class ScheduleTask {
private static final Logger Logger = Loggerfactory.getlogger (Scheduletask.class);
public void SayHello () {
Logger.info ("Hello World, I m the King of the World!!!");
}
}
Five, Quartz configuration class
Since Springboot pursues the 0 XML configuration, the following will be implemented as a configuration bean
Package com.chhliu.springboot.quartz.entity;
Import Org.quartz.Trigger;
Import Org.springframework.context.annotation.Bean;
Import org.springframework.context.annotation.Configuration;
Import Org.springframework.scheduling.quartz.CronTriggerFactoryBean;
Import Org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
Import Org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class Quartzconfigration {
/**
- Attention
Details: Configuring Timed Tasks
/
@Bean (name = "Jobdetail")
Public Methodinvokingjobdetailfactorybean Detailfactorybean (ScheduleTask Task) {//ScheduleTask for tasks that need to be performed
Methodinvokingjobdetailfactorybean jobdetail = new Methodinvokingjobdetailfactorybean ();
/
- Whether to execute concurrently
- For example, every 5s to perform a task, but the current task is not finished, it is already over 5s,
If true, the next task executes, and if false, the next task waits for the previous task to finish before it starts executing
*/
Jobdetail.setconcurrent (FALSE);
Jobdetail.setname ("Srd-chhliu");//Set the name of the task
Jobdetail.setgroup ("SRD");//Set the grouping of tasks, which can be stored in the database and used when multitasking
/*
The object that corresponds to the entity class that needs to be executed
*/
Jobdetail.settargetobject (Task);
/*
- SayHello for the method to be executed
- With these configurations, tell Jobdetailfactorybean that we need to perform timed execution of the SayHello method in the ScheduleTask class
*/
Jobdetail.settargetmethod ("SayHello");
return jobdetail;
}
/**
- Attention
Details: Configure triggers for timed tasks, that is, when to trigger the execution of timed tasks
/
@Bean (name = "Jobtrigger")
Public Crontriggerfactorybean Cronjobtrigger (Methodinvokingjobdetailfactorybean jobdetail) {
Crontriggerfactorybean Tigger = new Crontriggerfactorybean ();
Tigger.setjobdetail (Jobdetail.getobject ());
Tigger.setcronexpression ("0 *?"); /initial cron expression
Tigger.setname ("Srd-chhliu");//Trigger Name
return Tigger;
}
/**
- Attention
- Details: Defining the quartz dispatch factory
*/
@Bean (name = "Scheduler")
Public Schedulerfactorybean schedulerfactory (Trigger cronjobtrigger) {
Schedulerfactorybean bean = new Schedulerfactorybean ();
For quartz clusters, update existing jobs when Quartzscheduler started
Bean.setoverwriteexistingjobs (TRUE);
Delayed start, 1 seconds after application start
Bean.setstartupdelay (1);
Registering triggers
Bean.settriggers (Cronjobtrigger);
return bean;
}
}
Six, check the library regularly, and update the task
Package com.chhliu.springboot.quartz.entity;
Import Javax.annotation.Resource;
Import Org.quartz.CronScheduleBuilder;
Import Org.quartz.CronTrigger;
Import Org.quartz.JobDetail;
Import Org.quartz.Scheduler;
Import org.quartz.SchedulerException;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.context.annotation.Configuration;
Import org.springframework.scheduling.annotation.EnableScheduling;
Import org.springframework.scheduling.annotation.Scheduled;
Import org.springframework.stereotype.Component;
Import Com.chhliu.springboot.quartz.repository.ConfigRepository;
@Configurationbr/> @EnableScheduling
public class Schedulerefreshdatabase {br/> @Autowired
< p="">
@Resource (name = "Jobdetail") private jobdetail Jobdetail; @Resource (name = "Jobtrigger") Private Crontrigger Crontrigger ; @Resource (name = "Scheduler") private Scheduler Scheduler; @Scheduled (fixedrate = 5000)//Every 5s library, And depending on the query results, whether or not to reset the scheduled task public void Scheduleupdatecrontrigger () throws Schedulerexception {Crontrigger trigger = (Crontrigg ER) Scheduler.gettrigger (Crontrigger.getkey ()); String Currentcron = Trigger.getcronexpression ();//String Searchcron = Repository.findone (1L) used by the current trigger. Getcron (); SYSTEM.OUT.PRINTLN (Currentcron) queried from the database; System.out.println (Searchcron); if (Currentcron.equals (Searchcron)) {//If the cron expression currently in use is consistent with a cron expression queried from the database, the task is not refreshed} else {//Expression Scheduler Builder Cronschedulebuilder Schedulebuilder = Cronschedulebuilder.cronschedule (Searchcron); Rebuild Trigger Trigger = (Crontrigger) Scheduler.gettrigger (Crontrigger.getkey ()) According to the new cronexpression expression; Trigger = Trigger.gettriggerbuilder (). Withidentity (Crontrigger.getkeY ()). Withschedule (Schedulebuilder). build (); Press the new trigger to reset the job execution Scheduler.reschedulejob (Crontrigger.getkey (), trigger); Currentcron = Searchcron; }}
}
Vii. Related Scripts
1, Data.sql
Insert into config (Id,cron) VALUES (1, ' 0 0/2 *? '); # Perform a scheduled task every 2 minutes
2, Schema.sql
Drop table config if exists;
Create TABLE config (
ID bigint generated by default as identity,
Cron varchar (40),
Primary KEY (ID)
);
Eight, run the test
The test results are as follows: (quartz default thread pool size is 10)
0 ?
0 0/2 *?
2017-03-08 18:02:00.025 INFO 5328---[eduler_worker-1] c.c.s.quartz.entity.scheduletask:hello world, I ' m the king of th E World!!!
2017-03-08 18:04:00.003 INFO 5328---[eduler_worker-2] c.c.s.quartz.entity.scheduletask:hello world, I ' m the king of th E World!!!
2017-03-08 18:06:00.002 INFO 5328---[eduler_worker-3] c.c.s.quartz.entity.scheduletask:hello world, I ' m the king of th E World!!!
2017-03-08 18:08:00.002 INFO 5328---[eduler_worker-4] c.c.s.quartz.entity.scheduletask:hello world, I ' m the king of th E World!!!
Summary:
From the above log print time, we implemented a dynamic configuration, initially, the task is executed 20:30 every day, followed by dynamic refresh into every 2 minutes to execute.
Although the above solution does not use quartz recommended way perfect, but basically can meet our needs, of course, can also be implemented in the way of triggering events, such as the current side to modify the timing task of the trigger time, the asynchronous back to send notifications, the background received notification, and then update the program, Dynamic Scheduled task refresh can also be implemented
Springboot integrated quartz for dynamic configuration of Scheduled tasks