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,最好,支持分片配置
借鉴:https://www.cnblogs.com/mmzs/p/10161936.html
和java定时任务实现的4种方式_scheduledthreadpool.scheduleatfixedrate(timertask,-CSDN博客,还要自己的之前的东西