Java——定时任务框架quartz

1.简介

使用 @Scheduled 注解来解决简单的定时任务,大部分项目中可能都是使用 Quartz 来做定时任务。

Quartz是一个开源项目,专注于任务调度器,功能强大,提供了极为广泛的特性如持久化任务,集群和分布式任务等。 Quartz核心是调度器,还采用多线程管理。

持久化任务:当应用程序停止运行时,所有调度信息不被丢失,当你重新启动时,调度信息还存在,这就是持久化任务。
集群和分布式处理:当在集群环境下,当有配置Quartz的多个客户端(节点)时,
采用Quartz的集群和分布式处理时,简单了解几点

1)一个节点无法完成的任务,会被集群中拥有相同的任务的节点取代执行。
2)Quartz调度是通过触发器的类别来识别不同的任务,在不同的节点定义相同的触发器的类别,这样在集群下能稳定的运行,一个节点无法完成的任务,会被集群中拥有相同的任务的节点取代执行。
3)分布式 体现在 当相同的任务定时在一个时间点,在那个时间点,不会被两个节点同时执行。

2.使用

提前准备:
	1.导入依赖  spring-boot-starter-quartz
	2.在启动类上添加 @EnableScheduling 注解,表示开启定时任务。

需要定义一个Job(内包括一个jobDetail、trigger),然后把Job加入到调度器(scheduler)中。

2.1 定义 Job

Job 的定义有两种方式:

  1. 直接定义一个Bean,不支持传参。
@Component
public class MyJob1 {
 
    public void myTask1() {
        System.out.println("MyJob1 myTask1任务开始 : " + LocalDateTime.now().toLocalTime() + ",线程:" + Thread.currentThread().getName());
    }
}

  1. 定义一个Bean继承 QuartzJobBean类,并实现默认的方法,支持传参,任务启动时,executeInternal 方法将会被执行。
@Component
public class MyJob2 extends QuartzJobBean {
//    @Autowired  这里注入方式是不行的,报NPE
    private UserService userService;
 
    private Long id;
 
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        // 处理相应的注入service业务
        String data = userService.get(id);
        System.out.println(data);
        System.out.println("MyJob2 任务开始 : " + LocalDateTime.now().toLocalTime() + ",线程:" + Thread.currentThread().getName());
    }
 
    public UserService getUserService() {
        return userService;
    }
 
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
}

2.2 定义 JobDetail、Trigger

  1. JobDetail 的配置有两种方式:

(1)MethodInvokingJobDetailFactoryBean:可以配置目标 Bean 的名字和目标方法的名字,这种方式不支持传参。
(2)JobDetailFactoryBean:任务类继承自 QuartzJobBean ,这种方式支持传参,将参数封装在 JobDataMap 中进行传递。

  1. Quartz 中定义了多个 Trigger触发器,,这里使用下 SimpleTrigger 和 CronTrigger 。

SimpleTrigger触发器: 有点类似于上面的 @Scheduled 的基本用法。
CronTrigger触发器:支持 cron 表达式来配置任务执行时间

@Configuration
public class QuartzConfig {
    // MyJob2 需要 userService, 这两个都可以注入
//    @Bean
//    UserService userService() {
//        return new UserService();
//    }
    @Autowired
    private UserService userService;
 
    // MyJob1任务配置
    @Bean
    MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean() {
        MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
        bean.setTargetBeanName("myJob1"); // 首字母小写
        bean.setTargetMethod("myTask1");
        return bean;
    }
 
    @Bean
    SimpleTriggerFactoryBean simpleTriggerFactoryBean() {
        SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean();
        bean.setStartTime(new Date());
        bean.setRepeatCount(5);
        bean.setRepeatInterval(2000);
        bean.setJobDetail(methodInvokingJobDetailFactoryBean().getObject());
        return bean;
    }
 
    // MyJob2任务配置
    // 传参
    @Bean
    JobDetailFactoryBean jobDetailFactoryBean() {
        JobDetailFactoryBean bean = new JobDetailFactoryBean();
        bean.setJobClass(MyJob2.class);
        JobDataMap map = new JobDataMap();
        map.put("userService", userService);
        map.put("id", 101);
        bean.setJobDataMap(map);
        return bean;
    }
 
    @Bean
    CronTriggerFactoryBean cronTriggerFactoryBean() {
        CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
        bean.setCronExpression("0/5 * * * * ?");
        bean.setJobDetail(jobDetailFactoryBean().getObject());
        return bean;
    }
 
    // 添加 MyJob1和MyJob2的触发器
    @Bean
    SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        bean.setTriggers(cronTriggerFactoryBean().getObject(), simpleTriggerFactoryBean().getObject());
        return bean;
    }
 
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值