SpringBoot定时任务的两种方式



文章目录

  • SpringBoot定时任务的两种方式
  • 前言
  • 一、Spring scheduling是什么?
  • 1.开启定时任务注解@EnableScheduling
  • 2.@Scheduled添加定时任务注解
  • 3.Cron表达式
  • 二、Quartz定时任务实现
  • 1.定时任务启动流程
  • 2.具体实现
  • 1)具体任务,2种写法
  • 2)任务,2种写法
  • 3)触发器
  • 4)调度器
  • 5)手动调用代码(按需)
  • 总结



前言

主要是记录目前SpringBoot中常用的两种定时任务方式

  • 基于注解实现的Spring scheduling
  • 依赖Quartz框架实现复杂的定时任务

一、Spring scheduling是什么?

SpringBoot提供了定时任务的支持,通过注解简单快捷,对于日常定时任务可以使用,无需额外配置。

1.开启定时任务注解@EnableScheduling

@EnableScheduling
@SpringBootApplication
public class MyApplication {
  public static void main (String[] args) {
    SpringApplication.run(MyApplication.class,args);
  }
}

2.@Scheduled添加定时任务注解

@Component
public class Task1 {

 //每分钟运行一次
  @Scheduled(cron = "0 0/1 * * * ?")
  public void doTask1(){
    System.out.println("doTask1 " +System.currentTimeMillis());
  }
}

以上2步 就完成了定时任务的使用

3.Cron表达式

在线生成网站:https://qqe2.com/cron

二、Quartz定时任务实现

1.定时任务启动流程

SpringBoot 定时任务每周晚执行 springboot定时任务每天执行一次_spring


配置依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

2.具体实现

1)具体任务,2种写法

实现Job接口的这种写法,在之后代码中会有Service层服务无法注入的问题,不涉及此类操作的可以用

/**
 * @author nzh
 * @date 2022/8/19 8:11
 */
@Component
public class HelloJob implements Job{

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {

        System.out.println("现在的时间是 : " + DateUtil.date());
        System.out.println("hello world");
    }
}

继承 QuartzBean的方式,这种方式可以传参,把服务类当作属性接受,具体的业务逻辑代码在HiServiceImpl中

public class HiJob extends QuartzJobBean {

    HiServiceImpl hiService;

    public void setHiService(HiserviceImpl hiService) {
        this.hiService = hiService;
    }

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        System.out.println(hiService.sayHi());
    }
}

业务逻辑代码

@Service
public class HiServiceImpl {

    public String sayHi() {
        // hutool写法
        return "Hi 现在的时间是 : " + DateUtil.now();
    }
}

2)任务,2种写法

@Autowiredi
    HiServiceImpl hiService;

    @Bean
    MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean() {
        MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
        bean.setTargetBeanName("helloJob ");
        bean.setTargetMethod("execute");
        return bean;
    }


	//将Service传入Job实现类
    @Bean
    JobDetailFactoryBean jobDetailFactoryBean() {
        JobDetailFactoryBean bean = new JobDetailFactoryBean();
        bean.setJobClass(HiJob.class);
        JobDataMap data = new JobDataMap();
        data.put("hiService", hiService);
        bean.setJobDataMap(data);
        return bean;
    }

3)触发器

//相隔固定时间段执行,固定次数 可无限重复
 @Bean
    SimpleTriggerFactoryBean simpleTriggerFactoryBean() {
        SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean();
        bean.setRepeatCount(7);
        bean.setRepeatInterval(2000);
        bean.setStartTime(new Date());
        bean.setJobDetail(methodInvokingJobDetailFactoryBean().getObject());
        return bean;
    }

 //在特定时间点执行
 @Bean
    CronTriggerFactoryBean cronTriggerFactoryBean() {
        CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
        bean.setCronExpression("0/5 * * * * ?");
        bean.setJobDetail(jobDetailFactoryBean().getObject());
        return bean;
    }

4)调度器

这样就可以自动调用定时任务了,如果需要手动调用则把SetAutoStartup设置为false,默认为true

@Bean
    SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        bean.setTriggers(simpleTriggerFactoryBean().getObject());
        bean.setAutoStartup(true);
        return bean;
    }

    @Bean
    SchedulerFactoryBean schedulerFactoryBean1() {
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        bean.setTriggers(cronTriggerFactoryBean().getObject());
        bean.setAutoStartup(true);
        return bean;
    }

5)手动调用代码(按需)

@Component
@Slf4j
public class ApplicationRunnerImpl implements ApplicationRunner {

    @Autowired
    @Qualifier(value = "schedulerFactoryBean")
    SchedulerFactoryBean schedulerFactoryBean;
    
    @Autowired
    @Qualifier(value = "schedulerFactoryBean1")
    SchedulerFactoryBean schedulerFactoryBean1;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("项目启动成功,执行操作");
        schedulerFactoryBean.start();
        //schedulerFactoryBean1.start();
        //schedulerFactoryBean.stop();
        schedulerFactoryBean1.stop();
        System.out.println("冲冲冲,跑起来");
    }
}

总结

对定时任务的使用暂告一段落,综合了很多博客的写法,前几篇也有一些小踩坑总结,感谢各位大佬,完成了当前需求,如有不足,欢迎留言指教