Springboot实现定时器quartz应用举例。

上一篇中我们说明了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();
}
}
运行结果:(我们可以看到基于线程实现的)

Springboot实现定时器quartz应用举例。_第1张图片
就像上面我们实现的一样。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 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去更改调度的规则,这样方便我们图形界面的操作,而不是有需求要去改后台屎山代码,并且还可以持久化你的操作)
Springboot实现定时器quartz应用举例。_第2张图片
另外补充一段代码:(/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,文件导入执行即可。
Springboot实现定时器quartz应用举例。_第3张图片
共11张表。
Springboot实现定时器quartz应用举例。_第4张图片
另外新建一张表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


  
  


    
    
    
    
    
    
    
    
    





    insert into qrtz_task_info 
    values(#{taskId},
    #{jobName},
    #{jobGroup},
    #{jobClassName},
    #{triggerName},
    #{triggerGroup},
    #{createDate},
    #{corn})



对应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 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 getAllInfo(QuartzPojo pojo) throws Exception {
    //addPojo(pojo); // 第一次打开插入数据,后面注释掉
    System.out.println("开始查询");
    List 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 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 cls, String time, Map 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 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 jobClass,
                   String time, Map 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);        //通过触发器名和组名获取TriggerKey
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);                //通过TriggerKey获取CronTrigger
        if (trigger == null) {
            return;
        }
        String oldTime = trigger.getCronExpression();
        if (!oldTime.equalsIgnoreCase(time)) {
            JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);                        //通过任务名和组名获取JobKey
            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            Class 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);    //通过触发器名和组名获取TriggerKey
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);                //通过TriggerKey获取CronTrigger
        if (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);    //通过触发器名和组名获取TriggerKey
        JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);                        //通过任务名和组名获取JobKey
        scheduler.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);    //通过触发器名和组名获取TriggerKey
        JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);                            //通过任务名和组名获取JobKey
        scheduler.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 stub
    if (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 getBean(Class 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中功能抽出建成帮助类,目标类,实现类等即可完成。这也让我想到前段时间写权限框架时的问题,自己设计了一个超级复杂的权限,导致最后逻辑理不清楚,还在都还在理其中的逻辑(笨蛋)。

你可能感兴趣的:(spring系列)