In the new version of SpringBoot2.0
the release, I urge the early adopters of the relevant projects have been replaced by the latest version of the SpringBoot
source code GitHub
to see the update log, indicating for Quartz
was a new version of AutoConfiguration
automated configuration, save a lot of tedious configuration.
The core code implementation
quartz.properties basic configuration properties
###############内存版配置#################################### #org.quartz.scheduler.instanceName=spring-boot-quartz-demo #org.quartz.scheduler.instanceId=AUTO #org.quartz.threadPool.threadCount=5 #org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore ###############集群版配置#################################### org.quartz.scheduler.instanceName=spring-boot-quartz-demo org.quartz.scheduler.instanceId=AUTO org.quartz.scheduler.skipUpdateCheck=true org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount=5 org.quartz.threadPool.threadPriority=5 org.quartz.jobStore.misfireThreshold=60000 org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX #org.quartz.jobStore.dataSource=dataSource org.quartz.jobStore.tablePrefix=QRTZ_ org.quartz.jobStore.isClustered=true org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate org.quartz.jobStore.useProperties=false
Spring QuartzJobFactory.java poured into the container
package top.enjoyitlife.config; import org.quartz.spi.TriggerFiredBundle; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.scheduling.quartz.SpringBeanJobFactory; import org.springframework.stereotype.Component; @Component public class QuartzJobFactory extends SpringBeanJobFactory{ @Autowired private AutowireCapableBeanFactory capableBeanFactory; @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { Object jobInstance = super.createJobInstance(bundle); capableBeanFactory.autowireBean(jobInstance); return jobInstance; } }
QuartzConfig.java configuration class load configuration file to instantiate quartz and property to pay attention to the use of cluster programs need to connect to the database, and memory version is no configuration database
package top.enjoyitlife.config; import java.io.IOException; import java.util.Properties; import javax.sql.DataSource; import org.quartz.spi.JobFactory; import org.springframework.beans.factory.config.PropertiesFactoryBean; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.transaction.PlatformTransactionManager; @Configuration public class QuartzConfig { public static final String QUARTZ_PROPERTIES_PATH = "/quartz.properties"; @Bean public JobFactory jobFactory(ApplicationContext applicationContext) { QuartzJobFactory jobFactory = new QuartzJobFactory(); jobFactory.setApplicationContext(applicationContext); return jobFactory; } @Bean public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory,DataSource dataSource, PlatformTransactionManager transactionManager) throws IOException { SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setAutoStartup(true); factory.setJobFactory(jobFactory); factory.setQuartzProperties(quartzProperties()); //集群版配置 factory.setDataSource(dataSource); factory.setTransactionManager(transactionManager); return factory; } @Bean public Properties quartzProperties() throws IOException { PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean(); propertiesFactoryBean.setLocation(new ClassPathResource(QUARTZ_PROPERTIES_PATH)); propertiesFactoryBean.afterPropertiesSet(); return propertiesFactoryBean.getObject(); } }
Binding QuartzBindOperationConfig.java regular tasks include trigger CRON expression remarks task name task's group
package top.enjoyitlife.config; import org.quartz.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import top.enjoyitlife.schedule.TestSchedule; @Configuration public class QuartzBindOperationConfig { private Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private QuartzJobFactory quartzJobFactory; @Autowired private Scheduler scheduler; public void scheduleBind() { try { scheduler.setJobFactory(quartzJobFactory); JobDetail tesJobDetail = JobBuilder.newJob(TestSchedule.class) .withIdentity("tesJob", "tesJob").withDescription("定时任务demo") .build(); CronScheduleBuilder tesJobCronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/10 * * * * ?"); CronTrigger tesJobCronTrigger = TriggerBuilder.newTrigger() .withIdentity("tesJobTrigger", "tesJob") .withSchedule(tesJobCronScheduleBuilder).build(); scheduler.scheduleJob(tesJobDetail, tesJobCronTrigger); scheduler.start(); } catch (SchedulerException e) { // e.printStackTrace(); } } }
ApplicationListenerConfig.java project start initialization task that is loaded
package top.enjoyitlife.config; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Configuration; import org.springframework.context.event.ContextRefreshedEvent; @Configuration public class ApplicationListenerConfig implements ApplicationListener<ContextRefreshedEvent> { private Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private QuartzBindOperationConfig quartzBindOperationConfig; @Override public void onApplicationEvent(ContextRefreshedEvent event) { quartzBindOperationConfig.scheduleBind(); } }
TestSchedule.java testing tasks demo class
package top.enjoyitlife.schedule; import java.util.Date; import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @DisallowConcurrentExecution public class TestSchedule implements Job{ private Logger logger = LoggerFactory.getLogger(getClass()); @Override public void execute(JobExecutionContext context) throws JobExecutionException { logger.info("*****"+new Date()); } }
POM.xml quoted below
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>top.enjoyitlife</groupId> <artifactId>enjoyitlife</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>quartzDistribute</name> <description>quartz集群demo</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <repositories> <repository> <id>maven-ali</id> <url>http://maven.aliyun.com/nexus/content/groups/public//</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> <updatePolicy>always</updatePolicy> <checksumPolicy>fail</checksumPolicy> </snapshots> </repository> </repositories> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <dependency> <groupId>org.codehaus.janino</groupId> <artifactId>janino</artifactId> </dependency> <!-- 根据本地情况 进行对应调整--> <dependency> <groupId>com.oracle</groupId> <artifactId></ojdbc6artifactId> <version>11.2.0.4.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.3.5</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Run Log:
2019-05-11 16:11:20.076 INFO 9624 --- [Quartz_Worker-1] top.enjoyitlife.schedule.TestSchedule : *****Sat May 11 16:11:20 CST 2019 2019-05-11 16:11:30.037 INFO 9624 --- [Quartz_Worker-2] top.enjoyitlife.schedule.TestSchedule : *****Sat May 11 16:11:30 CST 2019 2019-05-11 16:11:40.033 INFO 9624 --- [Quartz_Worker-3] top.enjoyitlife.schedule.TestSchedule : *****Sat May 11 16:11:40 CST 2019
Server.port application.properties modify the port number, and then re-run QuartzDistributeApplication main method. The following is a screenshot of the double task of service at the same time start, there is now only 1 task logging service 2 no job history.
Stop Task 1 application, and then we will see the following log Print Task 2:
【Tips】
If you want to manually modify the expression CRON task in the cluster, you need to first modify CRON_EXPRESSION expression table QRTZ_CRON_TRIGGERS, and then modify the table QRTZ_TRIGGERS in the NEXT_FIRE_TIME and PREV_FIRE_TIME is 0, after the next task execution, the task execution interval on It will take effect.
To manually remove the timer task cluster, delete table records the following order: QRTZ_CRON_TRIGGERS -----> QRTZ_TRIGGERS ----> QRTZ_JOB_DETAILS, mainly due to the presence of the foreign key is deleted according to the order.