上一篇中我们说明了Springboot实现定时器quartz中文文档说明,
在开写主要内容前,我们来说明其他方式。
两者都是针对较简单的情况下。其一是,SpringBoot自带定时注解。其二是,定时线程池。
关于利用这两者前面已经实现、介绍过了,也给出(所有的只是为了更好的理解定时器)。
另外再讲一个自带的Timer来帮助理解(这三个都是三个基于线程来实现的)。

package com.cun;import java.util.Date;
import java.util.concurrent.TimeUnit;public class MyTimer extends Thread{private Long time ;public MyTimer(Long time) {this.time = time;
}@Override
public void run() {while(true){try {TimeUnit.SECONDS.sleep(time);} catch (InterruptedException e) {e.printStackTrace();}send();}
}
/***  开始执行任务*/
public void execute(){this.start();
}/***  定时任务*/
private void send() {System.out.println("任务执行了:" + new Date());
}public static void main(String[] args) {MyTimer myTimer = new MyTimer(2L); // 2 + L 表示2为long的数myTimer.execute();
}
}
运行结果:(我们可以看到基于线程实现的)


就像上面我们实现的一样。JDK已经有了这么类java.util.Timer;是这样定时器的功能。

package com.cun;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;public class TimerTest {public static void main(String[] args) {Timer timer = new Timer();// new Date() 马上执行任务,每隔1000执行一次,new Date()换成其他的就可以延迟执行timer.scheduleAtFixedRate(new MyTask(), new Date(), 1000);
}
}// 定时任务,这是一个线程
class MyTask extends TimerTask {
@Override
public void run() {System.out.println("task execute ");
}
}

以下运行结果就不给出了。
利用newScheduledThreadPool线程池,效率是很可以的(多任务也能执行)。

package com.cun;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;public class MyNewScheduledThreadPool {
public static void main(String[] args) throws InterruptedException,ExecutionException{ScheduledExecutorService service = Executors.newScheduledThreadPool(4);service.scheduleAtFixedRate(()->{ // 以固定的(频率)时间执行任务try {TimeUnit.MICROSECONDS.sleep(new Random().nextInt(1000));} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName());
}, 0, 1000000, TimeUnit.MICROSECONDS); // 从0(马上执行),之后每隔1000000毫秒执行一次。
}
}

SpringBoot自带的(适合简单的定时任务)

package com.cun;import java.util.Date;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = VsCodeApplication.class)
@EnableScheduling // 开启定时任务注解(这必须打开)
public class VsCodeApplicationTests {/** @Autowired private RedisTemplate<String, Object> redisTemplate;*/// 测试添加
@Test
@Scheduled(initialDelay=1000, fixedRate=5000)  // 第一次延迟1秒后执行,之后按fixedRate的规则每5秒执行一次
public void redisTest() {System.out.println("ok----------------" + new Date());
}
}

接下来便是主要内容(上面的是一次性执行,中途很难改变操作,面对复杂的调度,还是quartz):
上一篇介绍了很多,先来写个小程序,明白它的大致流程是怎么操作的。

package com.cun;import java.util.Date;import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/**
*  三要素之一,实现一共7步* @author zy962**/
// 1,创建MyJob
public class MyJob implements Job {private Logger Logger = LoggerFactory.getLogger(getClass());@Override
public void execute(JobExecutionContext context)throws JobExecutionException {// 取出任务名JobDetail detail = context.getJobDetail(); String name = detail.getJobDataMap().getString("name");Logger.info("开始执行:" + new Date());myTestTask();
}// 调用你的业务层代码。
private void myTestTask() {System.out.println("任务执行:" + new Date());
}public static void main(String[] args) throws InterruptedException {// 2,创建工厂SchedulerFactory schedulerfactory = new StdSchedulerFactory();Scheduler scheduler = null;try {// 2.1,通过schedulerFactory获取一个调度器scheduler = schedulerfactory.getScheduler();// 3,通过JobBuilder创建 JobDetail,指明job的名称,所在组的名称,以及绑定job类JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("JobName", "JobGroupName").usingJobData("name", "quartz").build();// 4,通过TriggerBuilder创建trigger,并定义触发的条件,立即触发,每3秒重复一次Trigger trigger = TriggerBuilder.newTrigger().withIdentity("CronTrigger1", "CronTriggerGroup").withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3).repeatForever()).startNow().build();// 5,把作业job和触发器注册到任务调度中scheduler.scheduleJob(job, trigger);// 6,启动调度scheduler.start();Thread.sleep(10000);// 7,停止调度scheduler.shutdown();} catch (SchedulerException e) {e.printStackTrace();}
}}

运行结果:(大致就这七个过程,其他的操作都是通过key去更改调度的规则,这样方便我们图形界面的操作,而不是有需求要去改后台屎山代码,并且还可以持久化你的操作)

另外补充一段代码:(/QuartzJobBean 有源码可以知道本质上还是Job差不多,这种方式可以避免不能注入bean的问题)

package com.taotao.store.order.job;import org.joda.time.DateTime;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;import com.taotao.store.order.mapper.OrderMapper;/*** 扫描超过2天未付款的订单关闭*/
public class PaymentOrderJob extends QuartzJobBean {@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().getJobDataMap().get("applicationContext");//时间参数,当前时间向前推2天applicationContext.getBean(OrderMapper.class).paymentOrderScan(new DateTime().minusDays(2).toDate());
}
}

构建场景:定时器简单每天定时查询数据库(操作你可以任意,随你喜欢,写得有点乱,但是还是说明了该说明的东西,这里提供一个思路如果想要耦合性高建议用反射调用)
下载包。对应版本,找到你所对应的数据库的sql,文件导入执行即可。

共11张表。

另外新建一张表qrtz_task_info用于存放定时任务基本信息和描述等信息

create table qrtz_task_info(task_id SERIAL primary key,job_name VARCHAR(120) NOT NULL,job_group VARCHAR(120) NOT NULL,job_class_name VARCHAR(120) NOT NULL,trigger_name VARCHAR(120) NOT NULL,trigger_group VARCHAR(120) NOT NULL,create_date VARCHAR(120) NOT NULL
);
// 建表是少建了一个字段。
alter table qrtz_task_info add cron VARCHAR(120);

数据库表对应的实体类:

package com.cun.quartz;import java.util.Date;import lombok.Data;@Data
public class QuartzPojo {private Integer taskId;
private String jobName;
private String jobGroup;
private String jobClassName;
private String triggerName;
private String triggerGroup;
private String corn; // 这个字段和数据库不一致,要额外注意
private Date createDate;}

对应的mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.cun.mapper.JobAndTriggerMapper">  <resultMap type="com.cun.quartz.QuartzPojo" id="QuartzPojo"><id property="taskId" column="task_id"/><result property="jobName" column="job_name"/><result property="jobGroup" column="job_group"/><result property="jobClassName" column="job_class_name"/><result property="triggerName" column="trigger_name"/><result property="triggerGroup" column="trigger_group"/><result property="createDate" column="create_date"/><result property="corn" column="cron"/><!-- <result property="createDate" column="create_date"/> -->
</resultMap><select id="getAllInfo" resultMap="QuartzPojo">SELECTtask_id,job_name,job_group,job_class_name,trigger_name,trigger_group,create_date,cronFROMqrtz_task_info
</select><insert id="addPojo" parameterType="com.cun.quartz.QuartzPojo">insert into qrtz_task_info values(#{taskId},#{jobName},#{jobGroup},#{jobClassName},#{triggerName},#{triggerGroup},#{createDate},#{corn})
</insert></mapper>

对应mapper

package com.cun.mapper;import java.util.List;import org.apache.ibatis.annotations.Mapper;import com.cun.quartz.QuartzPojo;// mapper注解一定要有
@Mapper
public interface JobAndTriggerMapper {public List<QuartzPojo> getAllInfo() throws Exception;// 在设定的是时间下插入数据
public void addPojo(QuartzPojo pojo) throws Exception;
}

service层逻辑:(接口就不给出了很简单)

package com.cun.serviceImpl;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import com.cun.mapper.JobAndTriggerMapper;
import com.cun.quartz.QuartzPojo;
import com.cun.service.JobAndTriggerService;@Service
public class JobAndTriggerServiceImpl implements JobAndTriggerService {@Autowired
private JobAndTriggerMapper mapper;@Override
public List<QuartzPojo> getAllInfo(QuartzPojo pojo) throws Exception {//addPojo(pojo); // 第一次打开插入数据,后面注释掉System.out.println("开始查询");List<QuartzPojo> list = mapper.getAllInfo();System.out.println(list);return list;
}@Override
public void addPojo(QuartzPojo pojo) throws Exception {mapper.addPojo(pojo);
}
}

定时任务类:

package com.cun.conf;import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;import com.cun.mapper.JobAndTriggerMapper;public class MyQuartzTask implements Job {@Autowired
private JobAndTriggerMapper mapper;private Logger logger = LoggerFactory.getLogger(getClass());@Override
public void execute(JobExecutionContext context)throws JobExecutionException {logger.info("任务开始执行");myTestTask();logger.info("任务已经执行结束");
}/*** 业务层代码*/
public void myTestTask() {try {logger.info("------------------------------开始");mapper.getAllInfo();} catch (Exception e) {e.printStackTrace();}
}}

我们的quartz工具类:

package com.cun.conf;import java.util.Map;import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/**
* 定时任务工具类* @author zy962**/
@Component
public class QuartzManagerUtil {/*** 注入任务调度器*/
@Autowired
private Scheduler scheduler;
private static String JOB_GROUP_NAME = "ATAO_JOBGROUP";                    //任务组
private static String TRIGGER_GROUP_NAME = "ATAO_TRIGGERGROUP";            //触发器组/*** 启动所有定时任务*/
public void startJobs() {try {scheduler.start();} catch (Exception e) {throw new RuntimeException(e);}
}/*** 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名** @param jobName 任务名* @param cls     任务* @param time    时间设置,参考quartz说明文档*/
public void addJob(String jobName, Class<? extends Job> cls, String time) {try {JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).build();    //用于描叙Job实现类及其他的一些静态信息,构建一个作业实例CronTrigger trigger = TriggerBuilder.newTrigger()                                                                        //创建一个新的TriggerBuilder来规范一个触发器.withIdentity(jobName, TRIGGER_GROUP_NAME)                                            //给触发器起一个名字和组名.withSchedule(CronScheduleBuilder.cronSchedule(time)).build();scheduler.scheduleJob(jobDetail, trigger);if (!scheduler.isShutdown()) {scheduler.start();      // 启动}} catch (Exception e) {throw new RuntimeException(e);}
}/*** 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名  (带参数)** @param jobName 任务名* @param cls     任务* @param time    时间设置,参考quartz说明文档*/
public void addJob(String jobName, Class<? extends Job> cls, String time, Map<String, Object> parameter) {try {JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).build();    //用于描叙Job实现类及其他的一些静态信息,构建一个作业实例jobDetail.getJobDataMap().put("parameterList", parameter);                                    //传参数CronTrigger trigger = TriggerBuilder.newTrigger()                                                                        //创建一个新的TriggerBuilder来规范一个触发器.withIdentity(jobName, TRIGGER_GROUP_NAME)                                            //给触发器起一个名字和组名.withSchedule(CronScheduleBuilder.cronSchedule(time)).build();scheduler.scheduleJob(jobDetail, trigger);if (!scheduler.isShutdown()) {scheduler.start();      // 启动}} catch (Exception e) {throw new RuntimeException(e);}
}/*** 添加一个定时任务** @param jobName          任务名* @param jobGroupName     任务组名* @param triggerName      触发器名* @param triggerGroupName 触发器组名* @param jobClass         任务* @param time             时间设置,参考quartz说明文档*/
public void addJob(String jobName, String jobGroupName,String triggerName, String triggerGroupName, Class<? extends Job> jobClass,String time) {try {JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();// 任务名,任务组,任务执行类CronTrigger trigger = TriggerBuilder     // 触发器.newTrigger().withIdentity(triggerName, triggerGroupName).withSchedule(CronScheduleBuilder.cronSchedule(time)).build();scheduler.scheduleJob(jobDetail, trigger);if (!scheduler.isShutdown()) {scheduler.start();      // 启动}} catch (Exception e) {throw new RuntimeException(e);}
}/*** 添加一个定时任务  (带参数)** @param jobName          任务名* @param jobGroupName     任务组名* @param triggerName      触发器名* @param triggerGroupName 触发器组名* @param jobClass         任务* @param time             时间设置,参考quartz说明文档*/
public void addJob(String jobName, String jobGroupName,String triggerName, String triggerGroupName, Class<? extends Job> jobClass,String time, Map<String, Object> parameter) {try {JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();// 任务名,任务组,任务执行类jobDetail.getJobDataMap().put("parameterList", parameter);                                //传参数CronTrigger trigger =  TriggerBuilder     // 触发器.newTrigger().withIdentity(triggerName, triggerGroupName).withSchedule(CronScheduleBuilder.cronSchedule(time)).build();scheduler.scheduleJob(jobDetail, trigger);if (!scheduler.isShutdown()) {scheduler.start();      // 启动}} catch (Exception e) {throw new RuntimeException(e);}
}/*** 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名)** @param jobName 任务名* @param time    新的时间设置*/
public void modifyJobTime(String jobName, String time) {try {TriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME);        //通过触发器名和组名获取TriggerKeyCronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);                //通过TriggerKey获取CronTriggerif (trigger == null) {return;}String oldTime = trigger.getCronExpression();if (!oldTime.equalsIgnoreCase(time)) {JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);                        //通过任务名和组名获取JobKeyJobDetail jobDetail = scheduler.getJobDetail(jobKey);Class<? extends Job> objJobClass = jobDetail.getJobClass();removeJob(jobName);addJob(jobName, objJobClass, time);}} catch (Exception e) {throw new RuntimeException(e);}
}/*** 修改一个任务的触发时间** @param triggerName      任务名称* @param triggerGroupName 传过来的任务名称* @param time             更新后的时间规则*/
public void modifyJobTime(String triggerName, String triggerGroupName, String time) {try {TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);    //通过触发器名和组名获取TriggerKeyCronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);                //通过TriggerKey获取CronTriggerif (trigger == null) return;CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(trigger.getCronExpression());String oldTime = trigger.getCronExpression();if (!oldTime.equalsIgnoreCase(time)) {trigger = (CronTrigger) trigger.getTriggerBuilder()        //重新构建trigger.withIdentity(triggerKey).withSchedule(scheduleBuilder).withSchedule(CronScheduleBuilder.cronSchedule(time)).build();scheduler.rescheduleJob(triggerKey, trigger);                //按新的trigger重新设置job执行}} catch (Exception e) {throw new RuntimeException(e);}
}/*** 移除一个任务(使用默认的任务组名,触发器名,触发器组名)** @param jobName 任务名称*/
public void removeJob(String jobName) {try {TriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME);    //通过触发器名和组名获取TriggerKeyJobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);                        //通过任务名和组名获取JobKeyscheduler.pauseTrigger(triggerKey);    // 停止触发器scheduler.unscheduleJob(triggerKey);// 移除触发器  scheduler.deleteJob(jobKey);        // 删除任务} catch (Exception e) {throw new RuntimeException(e);}
}/*** 移除一个任务** @param jobName          任务名* @param jobGroupName     任务组名* @param triggerName      触发器名* @param triggerGroupName 触发器组名*/
public void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) {try {TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);    //通过触发器名和组名获取TriggerKeyJobKey jobKey = JobKey.jobKey(jobName, jobGroupName);                            //通过任务名和组名获取JobKeyscheduler.pauseTrigger(triggerKey);    // 停止触发器scheduler.unscheduleJob(triggerKey);// 移除触发器  scheduler.deleteJob(jobKey);        // 删除任务} catch (Exception e) {throw new RuntimeException(e);}
}/*** 关闭所有定时任务*/
public void shutdownJobs() {try {if (!scheduler.isShutdown()) {scheduler.shutdown();}} catch (Exception e) {throw new RuntimeException(e);}
}
}

插入数据以及定时任务添加:

package com.cun.conf;import java.util.Date;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import com.cun.quartz.QuartzPojo;
import com.cun.serviceImpl.JobAndTriggerServiceImpl;@Component // 这个注解没什么意义可以删掉
public class QuartzSelect {public void timeTask() throws Exception {String jobName = "我的Quartz测试";String className = "com.cun.conf.MyQuartzTask";Class cls = Class.forName(className);String time = "0 46 23 ? * *"; // 每天23:30执行// 测试用数据QuartzPojo pojo = new QuartzPojo();pojo.setCorn(time);pojo.setCreateDate(new Date());pojo.setJobClassName(jobName);pojo.setJobGroup("myGroup");pojo.setTaskId(112);pojo.setTriggerGroup("triggerGroup");pojo.setTriggerName("triggerName");pojo.setJobName("myName");//  SpringUtils.getBean(JobAndTriggerServiceImpl.class)不能自动注入的解决方式JobAndTriggerServiceImpl service = SpringUtils.getBean(JobAndTriggerServiceImpl.class); service.getAllInfo(pojo);QuartzManagerUtil qManagerUtil = (QuartzManagerUtil) SpringUtils.getBean(QuartzManagerUtil.class);qManagerUtil.addJob(jobName, cls, time);
}
}

主类:

package com.cun;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.annotation.EnableScheduling;import com.cun.conf.QuartzSelect;
import com.cun.conf.SpringUtils;@SpringBootApplication
@MapperScan("com.cun.mapper")
@Import(SpringUtils.class) // 这个的作用解决不能自动注入
// @ComponentScan({"service"})
@EnableScheduling // 标注定时开启
public class VsCodeApplication {public static void main(String[] args) {SpringApplication.run(VsCodeApplication.class, args);try {new QuartzSelect().timeTask();} catch (Exception e) {e.printStackTrace();}
}
}

解决不能自动注入问题:

package com.cun.conf;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;/*** 解决无法注入问题* @author zy962**/
public final class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {// TODO Auto-generated method stubif (SpringUtils.applicationContext == null) {SpringUtils.applicationContext = applicationContext;}
}
public static ApplicationContext getApplicationContext() {return applicationContext;
}
//通过类名称获取Bean.
public static Object getBean(String name) {return getApplicationContext().getBean(name);
}
//通过class获取Bean.
public static <T> T getBean(Class<T> clazz){return getApplicationContext().getBean(clazz);
}
}

数据库结果:

运行log:(可以看到定时任务启动,结束等关键日志(以提取出关键))

// 定时器启动
2019-07-02 23:44:30 [main] INFO  org.quartz.core.QuartzScheduler -Scheduler quartzScheduler_$_NON_CLUSTERED started.
// 不定时检测是否触发trigger
2019-07-02 23:44:30 [quartzScheduler_QuartzSchedulerThread] DEBUG org.quartz.core.QuartzSchedulerThread -batch acquisition of 0 triggers
2019-07-02 23:44:55 [quartzScheduler_QuartzSchedulerThread] DEBUG org.quartz.core.QuartzSchedulerThread -batch acquisition of 0 triggers
2019-07-02 23:45:22 [quartzScheduler_QuartzSchedulerThread] DEBUG org.quartz.core.QuartzSchedulerThread -batch acquisition of 0 triggers
// 触发trigger
2019-07-02 23:45:46 [quartzScheduler_QuartzSchedulerThread] DEBUG org.quartz.core.QuartzSchedulerThread -batch acquisition of 1 triggers
2019-07-02 23:46:00 [quartzScheduler_QuartzSchedulerThread] DEBUG org.quartz.core.QuartzSchedulerThread -batch acquisition of 0 triggers
// 调用你的job任务
2019-07-02 23:46:00 [quartzScheduler_Worker-1] DEBUG org.quartz.core.JobRunShell -Calling execute on job ATAO_JOBGROUP.我的Quartz测试
// 任务开始执行
2019-07-02 23:46:00 [quartzScheduler_Worker-1] INFO  com.cun.conf.MyQuartzTask -任务开始执行
2019-07-02 23:46:00 [quartzScheduler_Worker-1] INFO  com.cun.conf.MyQuartzTask -------------------------------开始
2019-07-02 23:46:00 [quartzScheduler_Worker-1] DEBUG org.mybatis.spring.SqlSessionUtils -Creating a new SqlSession
2019-07-02 23:46:00 [quartzScheduler_Worker-1] DEBUG org.mybatis.spring.SqlSessionUtils -SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2cb9faad] was not registered for synchronization because synchronization is not active
2019-07-02 23:46:00 [quartzScheduler_Worker-1] DEBUG org.springframework.jdbc.datasource.DataSourceUtils -Fetching JDBC Connection from DataSource
2019-07-02 23:46:00 [quartzScheduler_Worker-1] DEBUG org.mybatis.spring.transaction.SpringManagedTransaction -JDBC Connection [org.postgresql.jdbc.PgConnection@7c369270] will not be managed by Spring
2019-07-02 23:46:00 [quartzScheduler_Worker-1] DEBUG com.cun.mapper.JobAndTriggerMapper.getAllInfo -==>  Preparing: SELECT task_id, job_name, job_group, job_class_name, trigger_name, trigger_group, create_date, cron FROM qrtz_task_info
2019-07-02 23:46:00 [quartzScheduler_Worker-1] DEBUG com.cun.mapper.JobAndTriggerMapper.getAllInfo -==> Parameters:
2019-07-02 23:46:00 [quartzScheduler_Worker-1] DEBUG com.cun.mapper.JobAndTriggerMapper.getAllInfo -<==      Total: 1
2019-07-02 23:46:00 [quartzScheduler_Worker-1] DEBUG org.mybatis.spring.SqlSessionUtils -Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2cb9faad]
// 任务已经执行结束
2019-07-02 23:46:00 [quartzScheduler_Worker-1] INFO  com.cun.conf.MyQuartzTask -任务已经执行结束
2019-07-02 23:46:29 [quartzScheduler_QuartzSchedulerThread] DEBUG org.quartz.core.QuartzSchedulerThread -batch acquisition of 0 triggers

感悟:写定时器遇到了很多的坑!但最搭的问题是一开始就想写个很复杂的定时任务。碰了一身灰,这就说明“万丈高楼平地起”真的没有错。我改变自己的想法,从最根本的定时任务开始分析,然后写一个小的demo运行成功。那么就下来就会简单很多,只需要你将demo中功能抽出建成帮助类,目标类,实现类等即可完成。这也让我想到前段时间写权限框架时的问题,自己设计了一个超级复杂的权限,导致最后逻辑理不清楚,还在都还在理其中的逻辑(笨蛋)。

Springboot实现定时器quartz应用举例。相关推荐

  1. quartz配置_基于spring-boot 2.x +quartz 的CRUD任务管理系统

    基于spring-boot 2.x + quartz 的CRUD任务管理系统,适用于中小项目. 开发环境 JDK1.8.Maven.Eclipse 技术栈 SpringBoot 2.0.1.thyme ...

  2. SpringBoot定时任务 - 集成quartz实现定时任务(单实例和分布式两种方式)

    最为常用定时任务框架是Quartz,并且Spring也集成了Quartz的框架,Quartz不仅支持单实例方式还支持分布式方式.本文主要介绍Quartz,基础的Quartz的集成案例本,以及实现基于数 ...

  3. java实现quartz定时器_java定时器quartz实现解析

    上次我们了解过了timer的有关内容,这次来了解下另外一个定时器quartz的实现,快来看看吧. 1.首先,在pom.xml中进行最重要也是基础的导包环节 org.quartz-scheduler q ...

  4. springBoot项目集成quartz开发定时任务案例及注意事项

    文章目录 quartz下载.安装 实战案例 常见问题及解决方案 quartz下载.安装 Quartz是完全由java开发的一个开源的任务日程管理系统,任务进度管理器就是一个在预先确定的时间到达时,负责 ...

  5. java quartz管理,SpringBoot中使用Quartz管理定时任务的方法

    定时任务在系统中用到的地方很多,例如每晚凌晨的数据备份,每小时获取第三方平台的 Token 信息等等,之前我们都是在项目中规定这个定时任务什么时候启动,到时间了便会自己启动,那么我们想要停止这个定时任 ...

  6. 使用spring-boot快速生成quartz所需的表

    使用spring-boot快速生成quartz表的步骤: 之前创建quartz表,都是别人建好的,或者在网上找一些sql文件,执行创建,今天发现通过quartz可以快速生成 1.创建spring-bo ...

  7. springboot 自动生成quartz表

    spring-boot 中自动生成 quartz 所需的表_冬无雪的博客-CSDN博客_quartz自动建表数据库 使用spring-boot快速生成quartz所需的表_wltian的博客-CSDN ...

  8. SpringBoot中实现quartz定时任务

    Quartz整合到SpringBoot(持久化到数据库) 背景 最近完成了一个小的后台管理系统的权限部分,想着要扩充点东西,并且刚好就完成了一个自动疫情填报系统,但是使用的定时任务是静态的,非常不利于 ...

  9. SSH框架中 Spring设置定时器 Quartz

    一,首先下载quartz-1.6.0.jar架包,到lib目录下 二,写你自己定时器业务方法 package com.lbnet.lzx.timing;import org.quartz.JobExe ...

最新文章

  1. 尽管苹果打死不认 但iCloud被破解是真的:媒体亲身验证
  2. Leave List-Processing 新解
  3. jpa 手动预编译_编译时检查JPA查询
  4. 《八佰》正式上映不到两天 累计票房破6亿元
  5. iOS: AFNetworking手动配置(iOS7.1, AF2.2.4)
  6. Atitit 图像处理类库 halcon11  安装与环境搭建attilax总结
  7. 几点预防内存泄露的小建议
  8. 神经网络 II:神经元模型
  9. 交互设计师到底是需要做什么?
  10. WPS的JS宏设置文档的表格底色
  11. 安卓源码目录最全解析
  12. 将iPad,iPhone或eReader的PDF电子书转换为ePub格式
  13. 设置PyCharm背景图片
  14. 全新版大学英语综合教程第一册学习笔记(原文及全文翻译)——7 - Kids On The Track(生死时刻)
  15. 玩转MAC OS!实测DIY兼容机装苹果系统
  16. 适合前端新手的十大网站
  17. st公司stm32MCU,cubemx创建工程,Drivers文件夹下内容不可见问题的描述与粗略解决方法
  18. Office 365 共享链接直接进入编辑
  19. Global Illumination_Spherical Harmonic Lighting(球谐光照)
  20. Java基础篇——面向对象编程

热门文章

  1. D3D11无双(2):渲染一个3D彩色立方体
  2. 【信号与系统】(十九)傅里叶变换与频域分析——LTI系统的频域分析
  3. 曾经的付费视频课持续放出,以及第6场【直播预告】
  4. python2 python3 安装激活虚拟环境
  5. winform控制textbox只能输入数字(小数)
  6. LLVM MC 简介
  7. 实例:用C#.NET手把手教你做微信公众号开发(2)--普通消息处理之文本
  8. javascript 获取指定国家(时区)的时间 - npm库
  9. 民勤一中2021高考成绩排名榜查询,2021年兰州高考状元多少分是谁,兰州高考状元名单资料...
  10. Twitter消息架构演进、移动Web技术的未来——QCon精彩话题前瞻