SpringBoot2.0接入quartz

SpringBoot的出现给我们带来了很多方便,基本上可以基于注解解决掉所有的配置,但是正因为它的迅速迭代,相关文档跟不上,所以有很多坑需要我们去踩,下面将给大家介绍Spinigboot2.0版本对接Quartz任务。

首先我们来了解一下spring常用的任务框架:

1.Spring Schedule

2.Quartz

Spring Schedule是Spring自带的任务框架,简单说他就是一个简化版本的Quartz,但是正因为它有个 与Springboot的集成非常简单,

@SpringBootApplication
@ComponentScan(basePackages = {"com.hik.tool","com.hik.dealexcel"})
@EnableCaching
@EnableScheduling
public class ProjectApplication extends SpringBootServletInitializer {

   public static void main(String[] args) {
      SpringApplication.run(ProjectApplication.class, args);
   }
}
只需要在springboot的启动类上加上

@EnableScheduling
然后写一个任务执行类,其中cron表示任务执行的时间表示式


@Component
public class ScheduledTask {
    @Scheduled(cron = "0 11 15 * * *")
    public void reportCurrentTimeCron() throws InterruptedException {
        System.out.println("任务执行!");
    }
}
这样就可以完成一个简单的定时任务,不需要依赖其他包,不需要任何配置,是不是很简单,但是这个定时其有个问题,据一位大佬的博客说,一旦某个任务在执行过程中抛出异常,则整个定时器生命周期就结束,以后永远不会再执行定时器任务,但是Quartz就不一样,上次任务出错不会影响下次任务的执行,所以我还是选择了quartz,那么我们开始进入今天正题。

    springboot在2.0版本之前,还没有出quartz的starter,所以集成起来相对麻烦点,需要引入多个jar包,然后做相关配置,但是2.0后,只需要引入starter就可以了,以下就是相关步骤(quartz的用法分为内存版本和数据库版本,这里主要讲解内存版本,springboot官方文档里面有讲到直接在application配置文件中如何切换成数据库版本,已经数据库相关信息的配置,总体比之前使用非starter简单很多):

1.引入starter


<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
2.编写任务类继承QuartzJobBean类,实现excuteInternal方法,方法中写自己需要定时执行的


public class UploadTask extends QuartzJobBean {
    @Resource
    private TencentYunService tencentYunService;
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("任务开始");
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("任务结束");
    }
}
3.创建一个配置类,分别制定具体任务类和触发的规则,我们可以和之前的xml配置对应起来看,

uploadTaskDetail指定了具体需要执行的类,只不过具体的方法就是我们需要实现的excuteInternal
uploadTaskTrigger指定了触发的规则

@Configuration
public class QuartzConfig {
    @Bean
    public JobDetail uploadTaskDetail() {
        return JobBuilder.newJob(UploadTask.class).withIdentity("uploadTask").storeDurably().build();
    }

    @Bean
    public Trigger uploadTaskTrigger() {
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("*/5 * * * * ?");
        return TriggerBuilder.newTrigger().forJob(uploadTaskDetail())
                .withIdentity("uploadTask")
                .withSchedule(scheduleBuilder)
                .build();
    }
}
<bean id="cleanupStatusTaskMethod" class= "org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
   <property name="targetObject" ref="cleanupStatusTask"/>
   <property name="targetMethod" value="cleanupStatus"/>
   <property name="concurrent" value="false"/>
</bean>

<bean id="cleanupStatusTrigger" class= "org.springframework.scheduling.quartz.SimpleTriggerBean">
   <property name="jobDetail" ref="cleanupStatusTaskMethod"/>
   <property name="startDelay" value="300000"/>
   <property name="repeatInterval" value="60000"/>
</bean>
如此一个Quartz集成Springboot就完成了,是不是很简单,在集成的过程中遇到了一个坑,我们看到在xml配置时我们配置了concurrent为false,这个意思是是否并发执行,系统默认为true,即第一个任务还未执行完整,第二个任务如果到了执行时间,则会立马开启新线程执行任务,这样如果我们是从数据库读取信息,两次重复读取可能出现重复执行任务的情况,所以我们需要将这个值设置为false,这样第二个任务会往后推迟,只有在第一个任务执行完成后才会执行第二个任务。

我们只需要在任务类上加入disallowconcurrentExeution就可以了


@DisallowConcurrentExecution
public class UploadTask extends QuartzJobBean {
    @Resource
    private TencentYunService tencentYunService;
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("任务开始");
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("任务结束");
    }
}
我们可以看一下效果,我们规定了任务每5s执行一次,而线程等待6秒,如果是并发执行会导致任务开始和任务结束杂乱出现

但是如果我们加上如上注解,那么只会成对先后出现开始和结束

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值