说明:该定时任务架构:springboot + mybatis + mysql + 独立模块
业务逻辑:
1.时间写在数据库,便于修改
2.在执行任务的方法上加定时刷新注解
3.方法内去数据库中获取定时,然后与当前定时做比较,如果相同不做改变;如果不相同修改定时
pom.xml
<?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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hxh</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>5.1.0</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.31</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
spring.datasource.name=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db_01?useSSL=false
spring.datasource.username=root
spring.datasource.password=hxh123456
mybatis.mapper-locations=classpath:mapper/*.xml
server.port=80
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
定时任务工厂类
package com.example.demo.config;
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;
import com.example.demo.task.ScheduleTask;
@Configuration
public class QuartzConfigration {
/** * * @param task 需要執行的任務 * @return 定时任务工厂类 */
@Bean(name = "jobDetail")
public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduleTask task) {
MethodInvokingJobDetailFactoryBean jobDetailFactoryBean = new MethodInvokingJobDetailFactoryBean();
/* * 是否并发执行 * 例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了, * 如果此处为true,则下一个任务会执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行 */
jobDetailFactoryBean.setConcurrent(false);
jobDetailFactoryBean.setName("detail-name");//设置任务名字
jobDetailFactoryBean.setGroup("a1");//设置任务分组,,这些属性都可以存储在数据库中,在多任务的时候使用
jobDetailFactoryBean.setTargetObject(task);//为需要执行的实体类对应的对象
jobDetailFactoryBean.setTargetMethod("sing");//需要执行task类中的方法
return jobDetailFactoryBean;
}
/** * Details:配置定时任务的触发器,也就是什么时候触发执行定时任务 * @param jobDetailFactoryBean * @return */
@Bean(name = "jobTrigger")
public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetailFactoryBean) {
CronTriggerFactoryBean triggerFactoryBean = new CronTriggerFactoryBean();
triggerFactoryBean.setJobDetail(jobDetailFactoryBean.getObject());
triggerFactoryBean.setCronExpression("0 30 20 * * ?");// 初始时的cron表达式
triggerFactoryBean.setName("detail-name");
return triggerFactoryBean;
}
/** * * @param trigger * @return */
@Bean(name = "scheduler")
public SchedulerFactoryBean schedulerFactory(Trigger trigger) {
SchedulerFactoryBean bean = new SchedulerFactoryBean();
// 用于quartz集群,QuartzScheduler 启动时更新己存在的Job
bean.setOverwriteExistingJobs(true);
// 延时启动,应用启动1秒后
bean.setStartupDelay(1);
// 注册触发器
bean.setTriggers(trigger);
return bean;
}
}
定时任务刷新定时类
package com.example.demo.task;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import javax.annotation.Resource;
import javax.net.ssl.HttpsURLConnection;
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;
importorg.springframework.stereotype.Component;
import com.example.demo.dao.QuartzDao;
import com.example.demo.entity.Config;
@Configuration
@EnableScheduling
@Component
public class ScheduleRefreshDatabase {
@Autowired
private QuartzDao dao;
@Resource(name = "jobDetail")
private JobDetail jobDetail;
@Resource(name = "jobTrigger")
private CronTrigger cronTrigger;
@Resource(name = "scheduler")
private Scheduler scheduler;
@Scheduled(fixedRate = 30000)
public void scheduleUpdateCronTrigger() throws SchedulerException, IOException {
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());
String currentCron = trigger.getCronExpression();
Config config = new Config();
config.setId(1l);
String searchCron = dao.findCron(config);
// System.out.println(currentCron);
// System.out.println(searchCron);
if (currentCron.equals(searchCron)) {
// URL url = new URL("http://localhost:8080/ssmredis2/redis/refurbish");
// URLConnection openConnection = url.openConnection();
// openConnection.connect();
// InputStream inputStream = openConnection.getInputStream();
// inputStream.close();
// URL url2 = openConnection.getURL();
// System.out.println(url2);
} else {
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(searchCron);
// 按新的cronExpression表达式重新构建trigger
trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());
trigger = trigger.getTriggerBuilder().withIdentity(cronTrigger.getKey())
.withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(cronTrigger.getKey(), trigger);
currentCron = searchCron;
}
定时任务方法实现类
package com.example.demo.task;
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
@EnableScheduling
public class ScheduleTask {
private static Logger LOGGER = LoggerFactory.getLogger(ScheduleTask.class);
public void sing() {
LOGGER.info("Hello world, i'm sing a song!!!");
}
}