Spring boot整合quartz定时任

 

Spring boot整合quartz定时任

 

创建工程

 

 

创建数据库和表

 

业务表

CREATE TABLE `basic_good_info` (
  `bgi_id` int(11) NOT NULL AUTO_INCREMENT,
  `bgi_name` varchar(255) DEFAULT NULL,
  `bgi_unit` varchar(255) DEFAULT NULL,
  `bgi_price` decimal(10,2) DEFAULT NULL,
  PRIMARY KEY (`bgi_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

 

 

quartz脚本

#
# In your Quartz properties file, you'll need to set 
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#
#
# By: Ron Cordell - roncordell
#  I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.

DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;

CREATE TABLE QRTZ_JOB_DETAILS(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_NONCONCURRENT VARCHAR(1) NOT NULL,
IS_UPDATE_DATA VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB;

CREATE TABLE QRTZ_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(200) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB;

CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;

CREATE TABLE QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
CRON_EXPRESSION VARCHAR(120) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;

CREATE TABLE QRTZ_SIMPROP_TRIGGERS
  (          
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    STR_PROP_1 VARCHAR(512) NULL,
    STR_PROP_2 VARCHAR(512) NULL,
    STR_PROP_3 VARCHAR(512) NULL,
    INT_PROP_1 INT NULL,
    INT_PROP_2 INT NULL,
    LONG_PROP_1 BIGINT NULL,
    LONG_PROP_2 BIGINT NULL,
    DEC_PROP_1 NUMERIC(13,4) NULL,
    DEC_PROP_2 NUMERIC(13,4) NULL,
    BOOL_PROP_1 VARCHAR(1) NULL,
    BOOL_PROP_2 VARCHAR(1) NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;

CREATE TABLE QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;

CREATE TABLE QRTZ_CALENDARS (
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(200) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
ENGINE=InnoDB;

CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;

CREATE TABLE QRTZ_FIRED_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(200) NULL,
JOB_GROUP VARCHAR(200) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID))
ENGINE=InnoDB;

CREATE TABLE QRTZ_SCHEDULER_STATE (
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
ENGINE=InnoDB;

CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME))
ENGINE=InnoDB;

CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);

CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);

CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);

commit; 

 

 

 

相关配置

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.youfan</groupId>
	<artifactId>springbootquartz</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>springbootquartz</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.8.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<druid.version>1.1.5</druid.version>
		<quartz.version>2.3.0</quartz.version>
		<fastjson.version>1.2.40</fastjson.version>
	</properties>

	<dependencies>
		<!--spring data jpa相关-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<!--web相关依赖-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!--数据库相关依赖-->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>${druid.version}</version>
		</dependency>
		<!--quartz相关依赖-->
		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz</artifactId>
			<version>${quartz.version}</version>
		</dependency>
		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz-jobs</artifactId>
			<version>${quartz.version}</version>
		</dependency>
		<!--定时任务需要依赖context模块-->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>${fastjson.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

 

quartz.properties

org.quartz.scheduler.instanceName = schedulerFactoryBean
org.quartz.scheduler.instanceId = AUTO
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.clusterCheckinInterval = 10000
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
#org.quartz.threadPool.makeThreadsDaemons=true
#org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

 

 

application.yml

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/quartz?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
    username: root
    password: 888888
  jpa:
    hibernate:
      ddl-auto: update #ddl-auto:设为update表示每次都不会重新建表
    show-sql: true
  application:
    name: quartz-cluster-node-first
server:
  port: 8081
#####################################################################################################
# 打印日志
logging:
  level:
    root: INFO
    org.hibernate: INFO
    org.hibernate.type.descriptor.sql.BasicBinder: TRACE
    org.hibernate.type.descriptor.sql.BasicExtractor: TRACE
    com.springms: DEBUG
#####################################################################################################

 

 

Quartz配置-QuartzConfiguration 

package com.youfan.config;

import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;

import javax.sql.DataSource;

/**
 * quartz定时任务配置
 */
@Configuration
@EnableScheduling
public class QuartzConfiguration {
    /**
     * 继承org.springframework.scheduling.quartz.SpringBeanJobFactory
     * 实现任务实例化方式
     */
    public static class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
        private transient AutowireCapableBeanFactory beanFactory;

        @Override
        public void setApplicationContext(final ApplicationContext context) {
            beanFactory = context.getAutowireCapableBeanFactory();
        }

        /**
         * 将job实例交给spring ioc托管
         * 我们在job实例实现类内可以直接使用spring注入的调用被spring ioc管理的实例
         *
         * @param bundle
         * @return
         * @throws Exception
         */
        @Override
        protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
            final Object job = super.createJobInstance(bundle);
            beanFactory.autowireBean(job);  //将job实例交付给spring ioc
            return job;
        }
    }

    /**
     * 配置任务工厂实例
     *
     * @param applicationContext spring上下文实例
     * @return
     */
    @Bean
    public JobFactory jobFactory(ApplicationContext applicationContext) {
        /**
         * 采用自定义任务工厂 整合spring实例来完成构建任务
         * see {@link AutowiringSpringBeanJobFactory}
         */
        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
        jobFactory.setApplicationContext(applicationContext);
        return jobFactory;
    }

    /**
     * 配置任务调度器
     * 使用项目数据源作为quartz数据源
     *
     * @param jobFactory 自定义配置任务工厂
     * @param dataSource 数据源实例
     * @return
     * @throws Exception
     */
    @Bean(destroyMethod = "destroy", autowire = Autowire.NO)
    public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory, DataSource dataSource) throws Exception {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        schedulerFactoryBean.setJobFactory(jobFactory);         // 将spring管理job自定义工厂交由调度器维护
        schedulerFactoryBean.setOverwriteExistingJobs(true);    // 设置覆盖已存在的任务
        schedulerFactoryBean.setStartupDelay(2);                // 项目启动完成后,等待2秒后开始执行调度器初始化
        schedulerFactoryBean.setAutoStartup(true);              // 设置调度器自动运行
        schedulerFactoryBean.setDataSource(dataSource);         // 设置数据源,使用与项目统一数据源
        schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContext");// 设置上下文spring bean name
        schedulerFactoryBean.setConfigLocation(new ClassPathResource("/quartz.properties"));// 设置配置文件位置
        return schedulerFactoryBean;
    }
}

说明:

    1)quartz的配置;

 

 

对商品的操作

GoodInfoEntity 

package com.youfan.goods.entity;

import lombok.Data;

import javax.persistence.*;
import java.math.BigDecimal;

@Entity
@Table(name = "basic_good_info")
@Data
public class GoodInfoEntity {
    /**
     * 商品编号
     */
    @Id
    @GeneratedValue
    @Column(name = "bgi_id")
    private Long id;
    /**
     * 商品名称
     */
    @Column(name = "bgi_name")
    private String name;
    /**
     * 商品单位
     */
    @Column(name = "bgi_unit")
    private String unit;
    /**
     * 商品单价
     */
    @Column(name = "bgi_price")
    private BigDecimal price;
}

说明:

    1)商品的实体bean;

 

GoodInfoRepository 

package com.youfan.goods.jpa;

import com.youfan.goods.entity.GoodInfoEntity;
import org.springframework.data.jpa.repository.JpaRepository;

public interface GoodInfoRepository extends JpaRepository<GoodInfoEntity,Long> {
}

说明:

    1)商品数据库的相关操作;

 

 

GoodInfoService

package com.youfan.goods.service;

import com.youfan.goods.entity.GoodInfoEntity;
import com.youfan.goods.jpa.GoodInfoRepository;
import com.youfan.timer.GoodAddTimer;
import com.youfan.timer.GoodSecKillRemindTimer;
import com.youfan.timer.GoodStockCheckTimer;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.UUID;

/**
 * 商品业务逻辑
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class GoodInfoService {
    /**
     * 注入任务调度器
     */
    @Autowired
    private Scheduler scheduler;
    /**
     * 商品数据接口
     */
    @Autowired
    private GoodInfoRepository goodInfoRepository;

    /**
     * 保存商品基本信息
     * @param good 商品实例
     * @return
     */
    public Long saveGood(GoodInfoEntity good) throws Exception {
        goodInfoRepository.save(good);

        buildCreateGoodTimer();                     // 构建创建商品定时任务
        buildGoodStockTimer();                      // 构建商品库存定时任务
        buildGoodSecKillRemindTimer(good.getId());  // 构建商品描述提醒定时任务
        return good.getId();
    }

    /**
     * 构建创建商品定时任务
     * 执行一次
     */
    public void buildCreateGoodTimer() throws Exception {
        long startAtTime = System.currentTimeMillis() + 1000 * 60;  // 设置开始时间为1分钟后
        String name = UUID.randomUUID().toString();                 // 任务名称
        String group = GoodAddTimer.class.getName();                // 任务所属分组
        JobDetail jobDetail = JobBuilder.newJob(GoodAddTimer.class).withIdentity(name,group).build();//创建任务
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity(name,group).startAt(new Date(startAtTime)).build();//创建任务触发器
        scheduler.scheduleJob(jobDetail, trigger);                  // 将触发器与任务绑定到调度器内
    }

    /**
     * 构建商品库存定时任务
     * 循环执行
     * @throws Exception
     */
    public void buildGoodStockTimer() throws Exception {
        String name = UUID.randomUUID().toString();                                                         // 任务名称
        String group = GoodStockCheckTimer.class.getName();                                                 // 任务所属分组
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/30 * * * * ?");
        JobDetail jobDetail = JobBuilder.newJob(GoodStockCheckTimer.class).withIdentity(name,group).build();//创建任务
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity(name,group).withSchedule(scheduleBuilder).build();//创建任务触发器
        scheduler.scheduleJob(jobDetail, trigger);//将触发器与任务绑定到调度器内
    }

    /**
     * 构建商品秒杀提醒定时任务
     * 设置五分钟后执行,传递业务参数
     * @throws Exception
     */
    public void buildGoodSecKillRemindTimer(Long goodId) throws Exception {
        String name = UUID.randomUUID().toString();                     // 任务名称
        String group = GoodSecKillRemindTimer.class.getName();          // 任务所属分组
        long startTime = System.currentTimeMillis() + 1000 * 5 * 60;    // 秒杀开始时间
        JobDetail jobDetail = JobBuilder.newJob(GoodSecKillRemindTimer.class).withIdentity(name,group).build();
        jobDetail.getJobDataMap().put("goodId",goodId);                 // 设置任务传递商品编号参数
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity(name,group).startAt(new Date(startTime)).build();//创建任务触发器
        scheduler.scheduleJob(jobDetail,trigger);                       //将触发器与任务绑定到调度器内
    }
}

说明:

    1)商品业务处理逻辑;

    2)商品添加后,分别执行3个任务:

        2.1)构建创建商品定时任务;

        2.2)构建商品库存定时任务;

        2.3)构建商品秒杀提醒定时任务;

 

 

GoodController

package com.youfan.goods.control;

import com.youfan.goods.entity.GoodInfoEntity;
import com.youfan.goods.service.GoodInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/good")
public class GoodController
{
    /**
     * 商品业务逻辑实现
     */
    @Autowired
    private GoodInfoService goodInfoService;
    /**
     * 添加商品
     * @return
     */
    @RequestMapping(value = "/save")
    public Long save(GoodInfoEntity good) throws Exception {
        return goodInfoService.saveGood(good);
    }
}

说明:

     1)对外提供接口调用;

 

 

 

定时任务的处理

GoodAddTimer 

package com.youfan.timer;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.util.Date;

/**
 * 商品添加定时任务实现类
 */
public class GoodAddTimer extends QuartzJobBean {

    static Logger logger = LoggerFactory.getLogger(GoodAddTimer.class);

    /**
     * 定时任务逻辑实现方法
     * 每当触发器触发时会执行该方法逻辑
     * @param jobExecutionContext 任务执行上下文
     * @throws JobExecutionException
     */
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        logger.info("分布式节点quartz-cluster-node-first,商品添加完成后执行任务,任务时间:{}",new Date());
    }
}

说明:

    1)模拟添加完后,任务执行;

 

 

 

GoodSecKillRemindTimer 

package com.youfan.timer;

import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;

/**
 * 商品秒杀提醒定时器
 * 为关注该秒杀商品的用户进行推送提醒
 */
public class GoodSecKillRemindTimer extends QuartzJobBean {
    private Logger logger = LoggerFactory.getLogger(GoodSecKillRemindTimer.class);

    /**
     * 任务指定逻辑
     * @param jobExecutionContext
     * @throws JobExecutionException
     */
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        JobDataMap dataMap = jobExecutionContext.getJobDetail().getJobDataMap();    // 获取任务详情内的数据集合
        Long goodId = dataMap.getLong("goodId");                                    // 获取商品编号
        logger.info("分布式节点quartz-cluster-node-first,开始处理秒杀商品:{},关注用户推送消息.",goodId);
    }
}

 说明:

    1)模拟定时秒杀前提醒;

    2)定时任务传递参数;

 

 

GoodStockCheckTimer 

package com.youfan.timer;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.util.Date;

/**
 * 商品库存检查定时任务
 */
public class GoodStockCheckTimer extends QuartzJobBean {
    static Logger logger = LoggerFactory.getLogger(GoodStockCheckTimer.class);

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        logger.info("分布式节点quartz-cluster-node-first,执行库存检查定时任务,执行时间:{}",new Date());
    }
}

说明:

    1)模拟定时检查库存任务处理;

 

 

 

启动类

package com.youfan;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * quartz定时任务分布式节点-1
 * 程序启动入口
 */
@SpringBootApplication
public class TestApplication {
	private static Logger logger = LoggerFactory.getLogger(TestApplication.class);
	public static void main(String[] args) {
		SpringApplication.run(TestApplication.class, args);
		logger.info("【【【【【【定时任务分布式节点 - quartz-cluster-node-first 已启动】】】】】】");
	}
}

 

测试类

package com.youfan.test;

import org.junit.Before;
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.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringRunner.class)
@SpringBootTest
	public class TestApplicationTests {
		/**
		 * 模拟mvc测试对象
		 */
		private MockMvc mockMvc;

		/**
		 * web项目上下文
		 */
		@Autowired
		private WebApplicationContext webApplicationContext;

		/**
		 * 所有测试方法执行之前执行该方法
		 */
		@Before
		public void before() {
			//获取mockmvc对象实例
			mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
		}

		/**
		 * 测试添加商品
		 * @throws Exception
		 */
		@Test
		public void addGood() throws Exception {
			MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/good/save")
					.param("name","西红柿")
					.param("unit","斤")
					.param("price","12.88")
			)
					.andDo(MockMvcResultHandlers.print())
					.andExpect(MockMvcResultMatchers.status().is(200))
					.andReturn();
			result.getResponse().setCharacterEncoding("UTF-8");
			System.out.println(result.getResponse().getContentAsString());
		}
}

控制台输出

2019-04-12 12:37:26.806  INFO 8732 --- [           main] com.youfan.TestApplication               : 【【【【【【定时任务分布式节点 - quartz-cluster-node-first 已启动】】】】】】
2019-04-12 12:37:28.737  INFO 8732 --- [lerFactoryBean]] o.s.s.quartz.SchedulerFactoryBean        : Starting Quartz Scheduler now, after delay of 2 seconds
2019-04-12 12:37:28.840  INFO 8732 --- [lerFactoryBean]] org.quartz.core.QuartzScheduler          : Scheduler schedulerFactoryBean_$_shangwu1555043845399 started.
2019-04-12 12:39:14.717  INFO 8732 --- [ryBean_Worker-1] com.youfan.timer.GoodStockCheckTimer     : 分布式节点quartz-cluster-node-first,执行库存检查定时任务,执行时间:Fri Apr 12 12:39:14 CST 2019
2019-04-12 12:39:30.172  INFO 8732 --- [ryBean_Worker-2] com.youfan.timer.GoodStockCheckTimer     : 分布式节点quartz-cluster-node-first,执行库存检查定时任务,执行时间:Fri Apr 12 12:39:30 CST 2019
2019-04-12 12:39:50.528  INFO 8732 --- [ryBean_Worker-3] com.youfan.timer.GoodAddTimer            : 分布式节点quartz-cluster-node-first,商品添加完成后执行任务,任务时间:Fri Apr 12 12:39:50 CST 2019
2019-04-12 12:40:00.113  INFO 8732 --- [ryBean_Worker-4] com.youfan.timer.GoodStockCheckTimer     : 分布式节点quartz-cluster-node-first,执行库存检查定时任务,执行时间:Fri Apr 12 12:40:00 CST 2019
2019-04-12 12:40:30.050  INFO 8732 --- [ryBean_Worker-5] com.youfan.timer.GoodStockCheckTimer     : 分布式节点quartz-cluster-node-first,执行库存检查定时任务,执行时间:Fri Apr 12 12:40:30 CST 2019
2019-04-12 12:41:00.304  INFO 8732 --- [ryBean_Worker-6] com.youfan.timer.GoodStockCheckTimer     : 分布式节点quartz-cluster-node-first,执行库存检查定时任务,执行时间:Fri Apr 12 12:41:00 CST 2019
2019-04-12 12:41:30.059  INFO 8732 --- [ryBean_Worker-7] com.youfan.timer.GoodStockCheckTimer     : 分布式节点quartz-cluster-node-first,执行库存检查定时任务,执行时间:Fri Apr 12 12:41:30 CST 2019
2019-04-12 12:42:00.116  INFO 8732 --- [ryBean_Worker-8] com.youfan.timer.GoodStockCheckTimer     : 分布式节点quartz-cluster-node-first,执行库存检查定时任务,执行时间:Fri Apr 12 12:42:00 CST 2019
2019-04-12 12:42:30.057  INFO 8732 --- [ryBean_Worker-9] com.youfan.timer.GoodStockCheckTimer     : 分布式节点quartz-cluster-node-first,执行库存检查定时任务,执行时间:Fri Apr 12 12:42:30 CST 2019
2019-04-12 12:43:00.115  INFO 8732 --- [yBean_Worker-10] com.youfan.timer.GoodStockCheckTimer     : 分布式节点quartz-cluster-node-first,执行库存检查定时任务,执行时间:Fri Apr 12 12:43:00 CST 2019
2019-04-12 12:43:30.055  INFO 8732 --- [ryBean_Worker-1] com.youfan.timer.GoodStockCheckTimer     : 分布式节点quartz-cluster-node-first,执行库存检查定时任务,执行时间:Fri Apr 12 12:43:30 CST 2019
2019-04-12 12:43:51.106  INFO 8732 --- [ryBean_Worker-2] com.youfan.timer.GoodSecKillRemindTimer  : 分布式节点quartz-cluster-node-first,开始处理秒杀商品:1,关注用户推送消息.
2019-04-12 12:44:00.054  INFO 8732 --- [ryBean_Worker-3] com.youfan.timer.GoodStockCheckTimer     : 分布式节点quartz-cluster-node-first,执行库存检查定时任务,执行时间:Fri Apr 12 12:44:00 CST 2019

说明:

1)商品添加完1分钟后执行【商品添加完成后执行任务】;

2)每个30秒执行【执行库存检查定时任务】;

3)5分钟后开始执行【开始处理秒杀商品】;

 

 

 


==============================
QQ群:143522604
群里有相关资源
欢迎和大家一起学习、交流、提升!
==============================

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Boot可以很方便地整合Quartz,只需要在pom.xml中添加相关依赖,然后在配置文件中配置Quartz相关属性即可。 具体步骤如下: 1. 在pom.xml中添加Quartz依赖: ``` <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version> </dependency> ``` 2. 在配置文件中配置Quartz相关属性: ``` spring.quartz.job-store-type=jdbc spring.quartz.jdbc.initialize-schema=always spring.quartz.properties.org.quartz.scheduler.instanceName=myScheduler spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate spring.quartz.properties.org.quartz.jobStore.dataSource=myDS spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_ spring.quartz.properties.org.quartz.dataSource.myDS.driverClassName=com.mysql.jdbc.Driver spring.quartz.properties.org.quartz.dataSource.myDS.URL=jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=utf-8&useSSL=false spring.quartz.properties.org.quartz.dataSource.myDS.user=root spring.quartz.properties.org.quartz.dataSource.myDS.password=root ``` 3. 创建Job类和Trigger类: ``` @Component public class MyJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("Hello, Quartz!"); } } @Configuration public class QuartzConfig { @Bean public JobDetail myJobDetail() { return JobBuilder.newJob(MyJob.class) .withIdentity("myJob") .storeDurably() .build(); } @Bean public Trigger myTrigger() { return TriggerBuilder.newTrigger() .forJob(myJobDetail()) .withIdentity("myTrigger") .withSchedule(CronScheduleBuilder.cronSchedule("/5 * * * * ?")) .build(); } } ``` 4. 在启动类中注入SchedulerFactoryBean并启动Quartz: ``` @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Autowired private SchedulerFactoryBean schedulerFactoryBean; @PostConstruct public void startQuartz() throws SchedulerException { schedulerFactoryBean.getScheduler().scheduleJob(quartzConfig.myJobDetail(), quartzConfig.myTrigger()); } } ``` 这样就完成了Spring Boot整合Quartz的配置。在启动应用程序时,Quartz自动创建表并启动时任务。 ### 回答2: Spring Boot是基于Spring Framework的快速应用开发框架,而Quartz是一个任务调度框架,可以帮助我们义和执行各种类型的后台作业。本文将为你介绍如何使用Spring Boot整合Quartz框架。 1. 添加依赖 在Spring Boot中使用Quartz需要添加以下依赖: ``` <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> <version>2.3.0</version> </dependency> ``` 2. 配置Job 在Quartz中,Job是需要执行的任务,我们需要义一个类来实现这个Job。 ``` public class MyJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 任务逻辑 } } ``` 3. 配置Trigger 在Quartz中,Trigger用于义任务执行的时间和频率。 ``` public class MyTrigger { public Trigger getTrigger() { return TriggerBuilder.newTrigger() .withIdentity("myTrigger", "group1") .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?")) .forJob("myJob", "group1") .build(); } } ``` 在上面的代码中,我们使用Cron表达式来义Job的执行时间。 4. 配置Scheduler 在Quartz中,Scheduler是最核心的部分,它负责管理所有的Job和Trigger,并按照预的时间执行任务。 ``` @Configuration public class SchedulerConfig { @Autowired private ApplicationContext applicationContext; @Bean public SchedulerFactoryBean schedulerFactoryBean() throws IOException { SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setQuartzProperties(quartzProperties()); factory.setJobFactory(springBeanJobFactory()); return factory; } @Bean public Properties quartzProperties() throws IOException { PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean(); propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties")); propertiesFactoryBean.afterPropertiesSet(); return propertiesFactoryBean.getObject(); } @Bean public SpringBeanJobFactory springBeanJobFactory() { AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory(); jobFactory.setApplicationContext(applicationContext); return jobFactory; } @Bean public Scheduler scheduler() throws IOException { return schedulerFactoryBean().getScheduler(); } @Bean public JobDetail myJobDetail() { return JobBuilder.newJob(MyJob.class) .withIdentity("myJob", "group1") .storeDurably() .build(); } @Bean public Trigger myTrigger() { return new MyTrigger().getTrigger(); } @PostConstruct public void init() throws SchedulerException, IOException { scheduler().addJob(myJobDetail(), true); scheduler().scheduleJob(myTrigger()); scheduler().start(); } } ``` 在上面的代码中,我们创建了一个SchedulerFactoryBean用于创建Scheduler实例,并在配置类中创建了多个Bean,包括JobDetail、Trigger和自义的SpringBeanJobFactory。 最后,在@PostConstruct注解下,我们将Job和Trigger添加到Scheduler实例中,并启动Scheduler开始任务调度。 5. 编写Quartz.properties文件 在resources目录下创建quartz.properties文件,用于配置Quartz的一些属性。 ``` org.quartz.scheduler.instanceName = MyScheduler org.quartz.threadPool.threadCount = 3 org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate org.quartz.jobStore.dataSource = myDS org.quartz.jobStore.tablePrefix = QRTZ_ org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/mydb org.quartz.dataSource.myDS.user = myuser org.quartz.dataSource.myDS.password = mypassword org.quartz.dataSource.myDS.maxConnections = 10 ``` 以上就是使用Spring Boot整合Quartz框架的全部步骤,通过以上步骤,我们可以轻松地创建和调度各种类型的后台任务。 ### 回答3: Spring Boot 是一个基于 Spring 框架的快速开发框架,使得构建Spring应用程序非常容易。Quartz 是一个用于作业调度的开源框架,可以通过义任务和调度器来实现任务的自动化调度。Spring BootQuartz 框架的整合,则可以帮助开发人员更加便捷地实现任务调度。 Spring Boot整合Quartz的步骤如下: 1.在 pom.xml 中添加 Quartz 的依赖: ```xml <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.0</version> </dependency> ``` 2.创建一个 Job 类,在该类中实现具体要执行的任务逻辑,并继承 org.quartz.Job 接口: ```java public class HelloWorldJob implements Job{ public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("Hello World."); } } ``` 3.在配置文件中添加 quartz 相关的配置,例如在 application.properties 文件中添加如下配置: ``` spring.quartz.job-store-type=jdbc spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123456 spring.quartz.jdbc.initialize-schema=always ``` 4.创建 SchedulerFactoryBean 类,用于创建调度器,并将 Job 注册到调度器中: ```java @Configuration public class QuartzConfig { @Autowired private DataSource dataSource; @Bean public JobDetail jobDetail() { return JobBuilder.newJob(HelloWorldJob.class) .withIdentity("helloJob") .storeDurably() .build(); } @Bean public Trigger trigger() { SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(10) .repeatForever(); return TriggerBuilder.newTrigger() .forJob(jobDetail()) .withIdentity("helloTrigger") .withSchedule(scheduleBuilder) .build(); } @Bean public SchedulerFactoryBean schedulerFactory() { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); schedulerFactoryBean.setDataSource(dataSource); schedulerFactoryBean.setJobDetails(jobDetail()); schedulerFactoryBean.setTriggers(trigger()); return schedulerFactoryBean; } } ``` 在 SchedulerFactoryBean 类中,首先创建了一个 JobDetail 类,用于描述 Job 相关的信息。然后,通过调用 TriggerBuilder 类的 newTrigger() 方法创建了一个 trigger,用于描述 Job 调度的策略和时间。最后,通过调用 SchedulerFactoryBean 的 setJobDetails() 方法和 setTriggers() 方法将 Job 和 trigger 注册到调度器中。 5.启动应用程序,任务就开始按照调度器中义的策略自动运行。 总的来说,Spring Boot整合Quartz非常容易,只需添加相应的依赖、编写 Job 类和 SchedulerFactoryBean 类,并在配置文件中添加相关的配置即可获得方便的任务调度功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值