中国建设银行网站无法访问,临沂网站制作加速企业发展,注册网站模板,做网站html和aspSpring boot开启定时任务的三种方式#xff08;内含源代码sql文件#xff09;
源代码sql文件下载链接地址#xff1a;https://download.csdn.net/download/weixin_46411355/87486580 目录Spring boot开启定时任务的三种方式#xff08;内含源代码sql文件#xff09;源代码…Spring boot开启定时任务的三种方式内含源代码sql文件
源代码sql文件下载链接地址https://download.csdn.net/download/weixin_46411355/87486580 目录Spring boot开启定时任务的三种方式内含源代码sql文件源代码sql文件下载链接地址[https://download.csdn.net/download/weixin_46411355/87486580](https://download.csdn.net/download/weixin_46411355/87486580)零、前言第一种也就是最简单的一种基于注解 (Scheduled)的方式第二种基于接口 (SchedulingConfigurer)第三种基于注解设定多线程定时任务。一、基于Scheduled注解的方式1.1 cron1.1.1 定时任务的方法在启动类里面1.1.2 定时任务的方法在启动类之外1.2 fixedDelay1.3 fixedRate1.4 initialDelay一点五 cron解释结构取值范围常例二、基于SchedulingConfigurer接口的方式2.1数据库准备2.2. 创建一个SpringBoot项目2.3 项目结构2.4 数据源基本配置application.properties2.5 mapper也就是dao2.6 task类MyTask.java2.7 使用上之前学的SpringBoot整合logback2.7.1 创建logback-spring.xml2.7.2 修改task类MyTask.java2.8 运行结果三、 基于注解设定多线程定时任务四、总结零、前言
spring boot进行定时任务一共有三种方式。
第一种也就是最简单的一种基于注解 (Scheduled)的方式
第二种基于接口 (SchedulingConfigurer)
第三种基于注解设定多线程定时任务。
一、基于Scheduled注解的方式
1.1 cron
首先打开idea创建springboot项目无需引入任何jarspringboot自带定时。
然后在启动类中用注解EnableScheduling进行标注表明此类 存在定时任务。
1.1.1 定时任务的方法在启动类里面
在定时执行的方法之上添加注解Scheduled(cron “*/6 * * * * ?”)。
package com.bjpowernode.springboottimedtask01at_scheduled_annotation;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;EnableScheduling
SpringBootApplication
public class SpringbootTimedtask01AtScheduledAnnotationApplication {public static void main(String[] args) {SpringApplication.run(SpringbootTimedtask01AtScheduledAnnotationApplication.class, args);}Scheduled(cron */6 * * * * ?)public void sayHello() {System.out.println(hello);}}
点击启动即可看到控制台6秒输出一次“hello”。
1.1.2 定时任务的方法在启动类之外
当然定时任务也可以放在其他类中。例如创建类Task1。
package com.bjpowernode.springboottimedtask01at_scheduled_annotation02.task;import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;Component
public class Task1 {Scheduled(cron */1 * * * * ?)public void sayWord() {System.out.println(world);}
}
然后可以看到控制台的输出结果 这里有个要注意的细节就是启动类需要能扫描到定时任务类否则定时任务启动不起来。不仅需要Component注解也需要将启动类位置位于定时任务类之上。如下图 笔者就是犯了这样的错一直没启动起来。
Scheduled除过cron还有三种方式fixedRatefixedDelayinitialDelay cron:表达式可以定制化执行任务但是执行的方式是与fixedDelay相近的也是会按照上一次方法结束时间开始算起。
1.2 fixedDelay
fixedDelay:控制方法执行的间隔时间是以上一次方法执行完开始算起如上一次方法执行阻塞住了那么直到上一次执行完并间隔给定的时间后执行下一次。
package com.bjpowernode.springboottimedtask01at_scheduld_annotationfixeddelay.task;import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;EnableScheduling//开启定时任务
Configuration
public class ScheduleTask1 {//每3秒执行一次Scheduled(fixedDelay 3000)private void myTask(){System.out.println(I do myself per third seconds);}
}
1.3 fixedRate
fixedRate:是按照一定的速率执行是从上一次方法执行开始的时间算起如果上一次方法阻塞住了下一次也是不会执行但是在阻塞这段时间内累计应该执行的次数当不再阻塞时一下子把这些全部执行掉而后再按照固定速率继续执行。
package com.bjpowernode.springboottimetask01at_scheduld_annotationfixedrate.task;import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;Component
EnableScheduling//开启定时事务
public class ScheduleTask2 {//每10s执行一次Scheduled(fixedRate 10000)public void myTask2(){System.out.println(我是一个定时任务);}
}
1.4 initialDelay
initialDelayinitialDelay 10000 表示在容器启动后延迟10秒后再执行一次定时器。
package com.bjpowernode.springboottimedtask01at_scheduld_annotationinitdelay.task;import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;EnableScheduling//开启定时任务
Component
public class ScheduleTask3 {//容器启动后延迟10秒再执行一次定时器以后每10秒再执行一次定时器Scheduled(initialDelay 10000,fixedRate 10000)private void myTask3(){System.out.println(我是一个定时任务);}}
一点五 cron解释
cron cron 用法跟linux下是一摸一样的如果你搞过linux下的定时那么必然很熟悉。
结构
cron表达式是一个字符串分为6或7个域每两个域之间用空格分隔
其语法格式为“秒域 分域 时域 日域 月域 周域 年域”
取值范围 常例 本方法的demo地址 GitHub - SUST-MaZhen/scheduledTask: 基于注解Scheluded的方式实现定时任务
二、基于SchedulingConfigurer接口的方式
使用Scheduled 注解很方便但缺点是当我们调整了执行周期的时候需要重启应用才能生效这多少有些不方便。为了达到实时生效的效果那么可以使用接口来完成定时任务统一将定时器信息存放在数据库中。
2.1数据库准备
在mysql中创建一个数据库 在mysql中执行一下脚本插入定时任务
drop table if exists scheduled;
create table scheduled (cron_id varchar(30) NOT NULL primary key,cron_name varchar(30) NULL,cron varchar(30) NOT NULL
);
insert into scheduled values (1,定时器任务一,0/6 * * * * ?);2.2. 创建一个SpringBoot项目
创建一个springboot 项目我们这里只添加一个mapper不要bean也不要service以及controller只是为了演示定时功能而已。
2.3 项目结构
demo结构
2.4 数据源基本配置application.properties
application.properties
## mysql数据源配置
spring.datasource.urljdbc:mysql://localhost:13306/powernode_scheduledtask?useUnicodetrueserverTimezoneAsia/Shanghai
spring.datasource.usernameroot
spring.datasource.passwordroot
spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver2.5 mapper也就是dao
package com.bjpowenode.springboottimetask02implementsscheduling_configureinterface.mapper;import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;Mapper
Repository
public interface CronMapper {Select(select cron from scheduled where cron_id #{id})public String getCron(int id);
}
2.6 task类MyTask.java
package com.bjpowenode.springboottimetask02implementsscheduling_configureinterface.scheduled;import com.bjpowenode.springboottimetask02implementsscheduling_configureinterface.mapper.CronMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;EnableScheduling
Component
public class MyTask implements SchedulingConfigurer{Autowiredprotected CronMapper cronMapper;Overridepublic void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {scheduledTaskRegistrar.addTriggerTask(//执行定时任务()-process(),//初始化定时任务周期triggerContext - {String cron cronMapper.getCron(1);if(cron.isEmpty()){System.out.println(cron is null);}return new CronTrigger(cron).nextExecutionTime(triggerContext);});}private void process(){System.out.println(基于接口定时任务);}
}2.7 使用上之前学的SpringBoot整合logback
2.7.1 创建logback-spring.xml
?xml version1.0 encodingUTF-8?
!-- 日志级别从低到高分为TRACE DEBUG INFO WARN ERROR FATAL如果设置为WARN则低于WARN的信息都不会输出 --
!-- scan:当此属性设置为true时配置文件如果发生改变将会被重新加载默认值为true --
!-- scanPeriod:设置监测配置文件是否有修改的时间间隔如果没有给出时间单位默认单位是毫秒。当scan为true时此属性生效。默认的时间间隔为1分钟。 --
!-- debug:当此属性设置为true时将打印出logback内部日志信息实时查看logback运行状态。默认值为false。 --
configuration scantrue scanPeriod10 seconds!--include resourceorg/springframework/boot/logging/logback/base.xml /--contextNamelogback/contextName!-- name的值是变量的名称value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后可以使“${}”来使用变量。 --property namelog.path valueD:/mylogs/ /!-- 彩色日志 --!-- 彩色日志依赖的渲染类 --conversionRule conversionWordclr converterClassorg.springframework.boot.logging.logback.ColorConverter /conversionRule conversionWordwex converterClassorg.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter /conversionRule conversionWordwEx converterClassorg.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter /!-- 彩色日志格式 --property nameCONSOLE_LOG_PATTERN value${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}/!--输出到控制台--appender nameCONSOLE classch.qos.logback.core.ConsoleAppender!--此日志appender是为开发使用只配置最低级别控制台输出的日志级别是大于或等于此级别的日志信息--filter classch.qos.logback.classic.filter.ThresholdFilterlevelinfo/level/filterencoderPattern${CONSOLE_LOG_PATTERN}/Pattern!-- 设置字符集 --charsetUTF-8/charset/encoder/appender!--输出到文件--!-- 时间滚动输出 level为 DEBUG 日志 --appender nameDEBUG_FILE classch.qos.logback.core.rolling.RollingFileAppender!-- 正在记录的日志文件的路径及文件名 --file${log.path}/log_debug.log/file!--日志文件输出格式--encoderpattern%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n/patterncharsetUTF-8/charset !-- 设置字符集 --/encoder!-- 日志记录器的滚动策略按日期按大小记录 --rollingPolicy classch.qos.logback.core.rolling.TimeBasedRollingPolicy!-- 日志归档 --fileNamePattern${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log/fileNamePatterntimeBasedFileNamingAndTriggeringPolicy classch.qos.logback.core.rolling.SizeAndTimeBasedFNATPmaxFileSize100MB/maxFileSize/timeBasedFileNamingAndTriggeringPolicy!--日志文件保留天数--maxHistory15/maxHistory/rollingPolicy!-- 此日志文件只记录debug级别的 --filter classch.qos.logback.classic.filter.LevelFilterleveldebug/levelonMatchACCEPT/onMatchonMismatchDENY/onMismatch/filter/appender!-- 时间滚动输出 level为 INFO 日志 --appender nameINFO_FILE classch.qos.logback.core.rolling.RollingFileAppender!-- 正在记录的日志文件的路径及文件名 --file${log.path}/log_info.log/file!--日志文件输出格式--encoderpattern%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n/patterncharsetUTF-8/charset/encoder!-- 日志记录器的滚动策略按日期按大小记录 --rollingPolicy classch.qos.logback.core.rolling.TimeBasedRollingPolicy!-- 每天日志归档路径以及格式 --fileNamePattern${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log/fileNamePatterntimeBasedFileNamingAndTriggeringPolicy classch.qos.logback.core.rolling.SizeAndTimeBasedFNATPmaxFileSize100MB/maxFileSize/timeBasedFileNamingAndTriggeringPolicy!--日志文件保留天数--maxHistory15/maxHistory/rollingPolicy!-- 此日志文件只记录info级别的 --filter classch.qos.logback.classic.filter.LevelFilterlevelinfo/levelonMatchACCEPT/onMatchonMismatchDENY/onMismatch/filter/appender!-- 时间滚动输出 level为 WARN 日志 --appender nameWARN_FILE classch.qos.logback.core.rolling.RollingFileAppender!-- 正在记录的日志文件的路径及文件名 --file${log.path}/log_warn.log/file!--日志文件输出格式--encoderpattern%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n/patterncharsetUTF-8/charset !-- 此处设置字符集 --/encoder!-- 日志记录器的滚动策略按日期按大小记录 --rollingPolicy classch.qos.logback.core.rolling.TimeBasedRollingPolicyfileNamePattern${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log/fileNamePatterntimeBasedFileNamingAndTriggeringPolicy classch.qos.logback.core.rolling.SizeAndTimeBasedFNATPmaxFileSize100MB/maxFileSize/timeBasedFileNamingAndTriggeringPolicy!--日志文件保留天数--maxHistory15/maxHistory/rollingPolicy!-- 此日志文件只记录warn级别的 --filter classch.qos.logback.classic.filter.LevelFilterlevelwarn/levelonMatchACCEPT/onMatchonMismatchDENY/onMismatch/filter/appender!-- 时间滚动输出 level为 ERROR 日志 --appender nameERROR_FILE classch.qos.logback.core.rolling.RollingFileAppender!-- 正在记录的日志文件的路径及文件名 --file${log.path}/log_error.log/file!--日志文件输出格式--encoderpattern%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n/patterncharsetUTF-8/charset !-- 此处设置字符集 --/encoder!-- 日志记录器的滚动策略按日期按大小记录 --rollingPolicy classch.qos.logback.core.rolling.TimeBasedRollingPolicyfileNamePattern${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log/fileNamePatterntimeBasedFileNamingAndTriggeringPolicy classch.qos.logback.core.rolling.SizeAndTimeBasedFNATPmaxFileSize100MB/maxFileSize/timeBasedFileNamingAndTriggeringPolicy!--日志文件保留天数--maxHistory15/maxHistory/rollingPolicy!-- 此日志文件只记录ERROR级别的 --filter classch.qos.logback.classic.filter.LevelFilterlevelERROR/levelonMatchACCEPT/onMatchonMismatchDENY/onMismatch/filter/appender!--logger用来设置某一个包或者具体的某一个类的日志打印级别、以及指定appender。logger仅有一个name属性一个可选的level和一个可选的addtivity属性。name:用来指定受此logger约束的某一个包或者具体的某一个类。level:用来设置打印级别大小写无关TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF还有一个特俗值INHERITED或者同义词NULL代表强制执行上级的级别。如果未设置此属性那么当前logger将会继承上级的级别。addtivity:是否向上级logger传递打印信息。默认是true。--!--logger nameorg.springframework.web levelinfo/--!--logger nameorg.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor levelINFO/--!--使用mybatis的时候sql语句是debug下才会打印而这里我们只配置了info所以想要查看sql语句的话有以下两种操作第一种把root levelinfo改成root levelDEBUG这样就会打印sql不过这样日志那边会出现很多其他消息第二种就是单独给dao下目录配置debug模式代码如下这样配置sql语句会打印其他还是正常info级别--!--root节点是必选节点用来指定最基础的日志输出级别只有一个level属性level:用来设置打印级别大小写无关TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF不能设置为INHERITED或者同义词NULL。默认是DEBUG可以包含零个或多个元素标识这个appender将会添加到这个logger。--!--开发环境:打印控制台--springProfile namedevlogger namecom.nmys.view leveldebug//springProfileroot levelinfoappender-ref refCONSOLE /appender-ref refDEBUG_FILE /appender-ref refINFO_FILE /appender-ref refWARN_FILE /appender-ref refERROR_FILE //root!--生产环境:输出到文件--!--springProfile namepro--!--root levelinfo--!--appender-ref refCONSOLE /--!--appender-ref refDEBUG_FILE /--!--appender-ref refINFO_FILE /--!--appender-ref refERROR_FILE /--!--appender-ref refWARN_FILE /--!--/root--!--/springProfile--/configuration2.7.2 修改task类MyTask.java package com.bjpowenode.springboottimetask02implementsscheduling_configureinterface.scheduled;import com.bjpowenode.springboottimetask02implementsscheduling_configureinterface.mapper.CronMapper;import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;import java.util.Date;Slf4j//直接采用lombok的注解即可
EnableScheduling
Component
public class MyTask implements SchedulingConfigurer{Autowiredprotected CronMapper cronMapper;Overridepublic void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {scheduledTaskRegistrar.addTriggerTask(//执行定时任务()-process(),//初始化定时任务周期triggerContext - {String cron cronMapper.getCron(1);if(cron.isEmpty()){System.out.println(cron is null);}return new CronTrigger(cron).nextExecutionTime(triggerContext);});}private void process(){log.info(new Date().toString());System.out.println(基于接口定时任务);}
}2.8 运行结果 从结果中可以看出是按照每6秒也就是数据库中查询的结果来进行的。
需求我现在需要每10秒执行一次定时任务该怎么办呢对只需要修改数据库值即可server无需重启。观察修改后的结果。 demo地址GitHub - SUST-MaZhen/scheduledtask2: springboot基于接口的定时任务
三、 基于注解设定多线程定时任务
前面讲到了Scheduled执行周期任务会受到上次一个任务的执行时间影响。那么可以开启多线程执行周期任务。
创建springboot项目 创建一个多线程定时任务类如下
package com.bjpowernode.springboottimedtask03at_scheduld_annotationmultithreadtask.task;import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;EnableAsync//2.开启多线程
EnableScheduling//1.开启定时任务
Component
public class MultiThreadTask {AsyncScheduled(fixedDelay 1000) //间隔1秒public void first() throws InterruptedException {System.out.println(第一个定时任务开始 : LocalDateTime.now().toLocalTime() \r\n线程 : Thread.currentThread().getName());Thread.sleep(1000 * 10);}AsyncScheduled(fixedDelay 2000)public void second() {System.out.println(第二个定时任务开始 : LocalDateTime.now().toLocalTime() \r\n线程 : Thread.currentThread().getName());}
}
执行结果如下
从结果可以看出第一个任务的执行时间也不受其本身执行时间的限制。两个任务也互不影响。
demo地址 GitHub - SUST-MaZhen/scheduledtash3: spring boot基于多线程的定时任务
四、总结
本文介绍了spring boot创建定时任务的三种方式当然还有其他方式