利用quartz实现定时调度

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 1、Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。这里我介绍quartz的两种方式。我这里搭建的框架是采用springboot、spring-data-jpa、mysql、quartz的方式来实现。

1、Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。这里我介绍quartz的两种方式。我这里搭建的框架是采用springboot、spring-data-jpa、mysql、quartz的方式来实现。

2、这里介绍的两种方式是:动态扫描的方式执行和注解的方式。

  至于xml的配置方式可以参考:http://www.cnblogs.com/ll409546297/p/7157702.html

3、动态扫描的方式

  1)基本的目录结构

  

  2)需要的基础包: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.troy</groupId>
    <artifactId>springbootquartz</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.7.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>1.5.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>1.5.7.RELEASE</version>
        </dependency>
        <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>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.3.11.RELEASE</version>
        </dependency>
    </dependencies>
</project>

  3)基本的yml配置application.yml  

server:
  port: 8080
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/model?useUnicode=true&amp;characterEncoding=utf8
    username: root
    password: root
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

  4)任务配置:TaskConfiguration.class

@Configuration
@EnableScheduling
public class TaskConfiguration {

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(){
        return new SchedulerFactoryBean();
    }
}

  5)实体需要的基础配置:ScheduleJob.class

@Entity
@Table
public class ScheduleJob {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String jobName;
    private String cronExpression;
    private String springId;
    private String methodName;
    private String jobStatus;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getJobName() {
        return jobName;
    }

    public void setJobName(String jobName) {
        this.jobName = jobName;
    }

    public String getCronExpression() {
        return cronExpression;
    }

    public void setCronExpression(String cronExpression) {
        this.cronExpression = cronExpression;
    }

    public String getSpringId() {
        return springId;
    }

    public void setSpringId(String springId) {
        this.springId = springId;
    }

    public String getMethodName() {
        return methodName;
    }

    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }

    public String getJobStatus() {
        return jobStatus;
    }

    public void setJobStatus(String jobStatus) {
        this.jobStatus = jobStatus;
    }
}

  6)基础数据访问配置和数据访问层:

@NoRepositoryBean
public interface BaseRepository<T,I extends Serializable> extends PagingAndSortingRepository<T,I>, JpaSpecificationExecutor<T> {
}
public interface ScheduleJobRepository extends BaseRepository<ScheduleJob,Long> {
    List<ScheduleJob> findAllByJobStatus(String jobStatus);
}

  7)SpringUtil.class

@Component
public class SpringUtil implements BeanFactoryPostProcessor {

    private static ConfigurableListableBeanFactory beanFactory;

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    public static Object getBean(String name) {
        return beanFactory.getBean(name);
    }
    public static <T> T getBean(Class<T> clazz){
        return beanFactory.getBean(clazz);
    }
}

  8)任务的调度工厂(主要是实现具体的执行)QuartzFactory.class

public class QuartzFactory implements Job {

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        //获取调度数据
        ScheduleJob scheduleJob = (ScheduleJob) jobExecutionContext.getMergedJobDataMap().get("scheduleJob");
        //获取对应的Bean
        Object object = SpringUtil.getBean(scheduleJob.getSpringId());
        try {
            //利用反射执行对应方法
            Method method = object.getClass().getMethod(scheduleJob.getMethodName());
            method.invoke(object);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

  9)具体的任务调度以及触发设置:TaskServiceImpl.class(略过接口)

@Service
@Transactional
public class TaskServiceImpl implements ITaskService {

    @Autowired
    private SchedulerFactoryBean schedulerFactoryBean;
    @Autowired
    private ScheduleJobRepository scheduleJobRepository;

    @Override
    public void timingTask() {
        //查询数据库是否存在需要定时的任务
        List<ScheduleJob> scheduleJobs = scheduleJobRepository.findAllByJobStatus("1");
        if (scheduleJobs != null) {
            scheduleJobs.forEach(this::execute);
        }
    }

    //添加任务
    private void execute(ScheduleJob scheduleJob){
        try {
            //声明调度器
            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            //添加触发调度名称
            TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName());
            //设置触发时间
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
            //触发建立
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
            //添加作业名称
            JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName());
            //建立作业
            JobDetail jobDetail = JobBuilder.newJob(QuartzFactory.class).withIdentity(jobKey).build();
            //传入调度的数据,在QuartzFactory中需要使用
            jobDetail.getJobDataMap().put("scheduleJob",scheduleJob);
            //调度作业
            scheduler.scheduleJob(jobDetail,trigger);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

  10)然后设置开机启动执行:TaskSchedule.class

@Component
public class TaskSchedule implements CommandLineRunner{

    @Autowired
    private ITaskService taskService;

    /**
     * 任务调度开始
     * @param strings
     * @throws Exception
     */
    @Override
    public void run(String... strings) throws Exception {
        System.out.println("任务调度开始==============任务调度开始");
        taskService.timingTask();
        System.out.println("任务调度结束==============任务调度结束");
    }
}

这里基础的配置就算完成了,然后就是在数据库进行相关的配置,项目启动的时候就开始扫描对应的表来执行具体的任务。

这里我写了一下简单的例子来实现。

  1)需要执行的方法:TaskInfoServiceImpl.class(略过接口)

@Service("taskInfo")
@Transactional
public class TaskInfoServiceImpl implements ITaskInfoService {
    @Override
    public void execute() {
        System.out.println("任务执行开始===============任务执行开始");
        System.out.println(new Date());
        System.out.println("任务执行结束===============任务执行结束");
    }
}

  2)数据库的配置(我这里测试用的每分钟0点执行)

  

测试结果:

4、注解的方式

  1)注解的方式相对动态配置来说简单的多,但是不便于管理。注解的方式需要的基础包,和上面基本上差不多

  2)这里我写了一下简单的例子来实现:TaskExcuteServiceImpl.class

@Service
@Transactional
public class TaskExcuteServiceImpl implements ITaskExcuteService {

    @Scheduled(cron = "30 * * * * ?")
    @Override
    public void excute() {
        System.out.println("注解执行开始==============注解执行开始");
        System.out.println(new Date());
        System.out.println("注解执行结束==============注解执行结束");
    }
}

  3)测试结果为:

  

 

 

5、有需要源码的可以自己下载:https://pan.baidu.com/s/1pLSLdTT

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
Java 调度 Maven
定时任务组件Quartz
定时任务组件Quartz
定时任务组件Quartz
|
存储 运维 Java
分布式定时任务-Quartz
分布式定时任务-Quartz
分布式定时任务-Quartz
调度介绍 - Quartz
众所周知,Quartz作为知名的企业级调度框架,提供了丰富的特性。本文通过一个简单的示例,介绍下quartz在springboot的应用和quartz部分基本概念,并展示了quartz调度作业的基本过程。
调度介绍 - Quartz
|
调度
Quartz的CronScheduleBuilder和Cron表达式(五)下
Quartz的CronScheduleBuilder和Cron表达式(五)下
339 0
Quartz的CronScheduleBuilder和Cron表达式(五)下
|
前端开发 Linux 调度
Quartz的CronScheduleBuilder和Cron表达式(五)上
Quartz的CronScheduleBuilder和Cron表达式(五)上
925 0
Quartz的CronScheduleBuilder和Cron表达式(五)上
Quartz 定时任务管理类
Quartz 定时任务管理类
162 0
|
前端开发 Java 调度
Quartz 定时器任务调度
Job:是一个接口只有一个方法void execute(JobExecutionContext context),开发者实现该接口定义运行任务,JobExecutionContext类提供了调度上下文的各种信息。Job运行时的信息保存在 JobDataMap实例中 第一种,作业类继承自特定的基  1.8测试成功,2.0不行类:org.springframework.scheduling.
1888 0
|
Linux
Quartz job.xml配置的Cron表达式详解
Quartz使用类似于Linux下的Cron表达式定义时间规则,Cron表达式由6或7个由空格分隔的时间字段组成。 Cron表达式时间字段: 位置 时间域名 允许值 允许的特殊字符 1 秒 0-59 , - * / 2 分钟 0-59 ...
1558 0