1、 定义在数据库中
1、导入依赖包:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.0.4.RELEASE</version>
</parent>
<dependencies>
<dependency><!--添加Web依赖 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><!--添加MySql依赖 -->
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency><!--添加Mybatis依赖 配置mybatis的一些初始化的东西-->
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<dependency><!-- 添加mybatis依赖 -->
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
<scope>compile</scope>
</dependency>
</dependencies>
2、添加数据库记录:
开启本地数据库mysql,随便打开查询窗口,然后执行脚本内容,如下:
DROP DATABASE IF EXISTS `socks`;
CREATE DATABASE `socks`;
USE `SOCKS`;
DROP TABLE IF EXISTS `cron`;
CREATE TABLE `cron` (
`cron_id` varchar(30) NOT NULL PRIMARY KEY,
`cron` varchar(30) NOT NULL
);
INSERT INTO `cron` VALUES ('1', '0/5 * * * * ?');
spring:
datasource:
url: jdbc:mysql://localhost:3306/socks
username: root
password: 123456
3、创建定时器
数据库准备好数据之后,我们编写定时任务,注意这里添加的是TriggerTask,目的是循环读取我们在数据库设置好的执行周期,以及执行相关定时任务的内容。
具体代码如下:
@Configuration //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling // 2.开启定时任务
public class DynamicScheduleTask implements SchedulingConfigurer {
@Mapper
public interface CronMapper {
@Select("select cron from cron limit 1")
public String getCron();
}
@Autowired //注入mapper
@SuppressWarnings("all")
CronMapper cronMapper;
/**
* 执行定时任务.
*/
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(
//1.添加任务内容(Runnable)
() -> System.out.println("执行动态定时任务: " + LocalDateTime.now().toLocalTime()),
//2.设置执行周期(Trigger)
triggerContext -> {
//2.1 从数据库获取执行周期
String cron = cronMapper.getCron();
//2.2 合法性校验.
if (StringUtils.isEmpty(cron)) {
// Omitted Code ..
}
//2.3 返回执行周期(Date)
return new CronTrigger(cron).nextExecutionTime(triggerContext);
}
);
}
}
2、定义在Apollo中:
package com.Schedule;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @Description :定时任务配置在Apollo
* @Author lishuangqiang
* @Date 2021/1/26
**/
@Slf4j
@Component
public class DynamicScheduleTaskInApollo {
/**
* 其中corntest为配置在Apollo上的corn表达式
*/
@Scheduled(cron = "${corntest}")
public void test1() {
log.info("定时任务开始 :{} ,线程 : {}", LocalDateTime.now().toLocalTime());
}
@Value("${timeApollo}")
private Long timeApollo;
@PostConstruct
public void test2() {
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
log.info("handleRemindWay2定时任务开始 :{} ,线程 : {}", LocalDateTime.now().toLocalTime(), Thread.currentThread().getName());
log.info("=========================");
}
}, timeApollo, timeApollo, TimeUnit.MILLISECONDS);
}
}
3、用quartz方式 其中定时任务的表达式也可以配置在Apollo
@Configuration
public class QuartzConfig {
@Resource
private ScheduleTask scheduleTask;
/**
* 配置定时任务1
* @return
*/
@Bean(name="firstJobDetail")
public MethodInvokingJobDetailFactoryBean firstJobDetail(){
MethodInvokingJobDetailFactoryBean method = new MethodInvokingJobDetailFactoryBean();
// 为需要执行的实体类对应的对象
method.setTargetObject(scheduleTask);
// 需要执行的方法
method.setTargetMethod("test");
// 是否并发执行
method.setConcurrent(false);
return method;
}
/**
* 配置触发器1
* @param firstJobDetail
* @return
*/
@Bean(name="firstTrigger")
public SimpleTriggerFactoryBean firstTrigger(JobDetail firstJobDetail){
SimpleTriggerFactoryBean simpleBean = new SimpleTriggerFactoryBean();
simpleBean.setJobDetail(firstJobDetail);
// 设置任务启动延迟
simpleBean.setStartDelay(1000);
// 每1秒执行一次
simpleBean.setRepeatInterval(1000);
//设置重复计数
//simpleBean.setRepeatCount(0);
return simpleBean;
}
/**
* 配置Scheduler
*/
@Bean(name = "scheduler")
public SchedulerFactoryBean schedulerFactoryBean(Trigger firstTrigger){
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
factoryBean.setTriggers(firstTrigger);
return factoryBean;
}
}
@Component
public class ScheduleTask {
public void test() {
System.out.println("====================================");
}
}
4、把参数配置到.properties文件中
package com.accord.task;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ScheduledTask {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
//@Scheduled(fixedDelayString = "${jobs.fixedDelay}")
@Scheduled(fixedDelayString = "2000")
public void getTask1() {
System.out.println("任务1,从配置文件加载任务信息,当前时间:" + dateFormat.format(new Date()));
}
@Scheduled(cron = "${jobs.cron}")
public void getTask2() {
System.out.println("任务2,从配置文件加载任务信息,当前时间:" + dateFormat.format(new Date()));
}
}
application.properties文件:
jobs.fixedDelay=5000
jobs.cron=0/5 * * * * ?
上面的方式在做定时任务 时有多个机器最好用redission做分布式锁方式防止重复调用,当然这样的情况最好用业界的xxl-JOB或者elastic-job,最好,支持分片配置
借鉴:www.cnblogs.com/mmzs/p/1016…
和java定时任务实现的4种方式_scheduledthreadpool.scheduleatfixedrate(timertask,-CSDN博客,还要自己的之前的东西