定时任务 Springboot+quartz+service层不能注入的问题

1 添加依赖

   

 <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-jobs</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.0</version>
        </dependency>
View Code

2   创建Factory(代码可照抄)

package com.souche.salt_common_01.config;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;

@Component
public class MyJobFactory extends AdaptableJobFactory {
    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;

    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        // 调用父类的方法
        Object jobInstance = super.createJobInstance(bundle);
        // 进行注入
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}
View Code

3  创建配置文件(代码可照抄)

package com.souche.salt_common_01.config;

import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;


@Configuration
public class QuartzConfig {
    @Autowired
    private MyJobFactory myJobFactory;


    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        schedulerFactoryBean.setJobFactory(myJobFactory);
        System.out.println("myJobFactory:"+myJobFactory);
        return schedulerFactoryBean;
    }




    @Bean
    public Scheduler scheduler() {
        return schedulerFactoryBean().getScheduler();
    }


}
View Code

4 创建job 定时执行此job里面的方法(你要执行的业务代码在这里面)

package com.souche.salt_common_01.service.impl;

import com.souche.salt_common_01.controller.SctiptsController;
import com.souche.salt_common_01.controller.TimeJobController;
import com.souche.salt_common_01.entity.JobsLog;
import com.souche.salt_common_01.entity.Scripts;
import com.souche.salt_common_01.entity.ScriptsExample;
import com.souche.salt_common_01.mapper.ScriptsMapper;
import com.souche.salt_common_01.service.ClientService;
import com.souche.salt_common_01.utils.IDUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;


public class SchedulerQuartzJob1 implements Job{


    @Autowired
    private TimeJobController timeJobController;




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

            System.out.println("开始:"+System.currentTimeMillis());
           //此处可获得你要执行的名字              
        String JobName=arg0.getJobDetail().getKey().getName();
            


        System.out.println("结束:"+System.currentTimeMillis());



    }








}

5 创建配置文件(可照抄 )

我只试用过第一个方法startJob 新建一个任务:传入任务名 ,执行时间两个参数,执行时间是cron表达式

package com.souche.salt_common_01.config;

import java.util.Date;

import com.souche.salt_common_01.service.impl.SchedulerQuartzJob1;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;


/**
 * 任务调度处理
 * @author yvan
 *
 */
@Configuration
public class QuartzScheduler {
    // 任务调度
    @Autowired
    private Scheduler scheduler;

    /**
     * 开始执行所有任务
     *
     * @throws SchedulerException
     */
    public void startJob(String jobName,String startTime) throws SchedulerException {
        //startJob1(scheduler,name,startTime);
        // 通过JobBuilder构建JobDetail实例,JobDetail规定只能是实现Job接口的实例
        // JobDetail 是具体Job实例
        JobDetail jobDetail = JobBuilder.newJob(SchedulerQuartzJob1.class).withIdentity(jobName, "group1").build();
        // 基于表达式构建触发器
       // CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(startTime);
        // CronTrigger表达式触发器 继承于Trigger
        // TriggerBuilder 用于构建触发器实例
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(jobName, "group1")
                .withSchedule(cronScheduleBuilder).build();
        scheduler.scheduleJob(jobDetail, cronTrigger);
        scheduler.start();
    }

    /**
     * 获取Job信息
     *
     * @param name
     * @param group
     * @return
     * @throws SchedulerException
     */
    public String getJobInfo(String name, String group) throws SchedulerException {
        TriggerKey triggerKey = new TriggerKey(name, group);
        CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        return String.format("time:%s,state:%s", cronTrigger.getCronExpression(),
                scheduler.getTriggerState(triggerKey).name());
    }

    /**
     * 修改某个任务的执行时间
     *
     * @param name
     * @param group
     * @param time
     * @return
     * @throws SchedulerException
     */
    public void modifyJob(String name, String group, String time) throws SchedulerException {
        Date date = null;
        System.err.println(name);
        System.err.println(group);
        TriggerKey triggerKey = new TriggerKey(name, group);
        CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        String oldTime = cronTrigger.getCronExpression();
        if (!oldTime.equalsIgnoreCase(time)) {
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(time);
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(name, group)
                    .withSchedule(cronScheduleBuilder).build();
            date = scheduler.rescheduleJob(triggerKey, trigger);
        }
      //  return date != null?true:false;
    }

    /**
     * 暂停所有任务
     *
     * @throws SchedulerException
     */
    public void pauseAllJob() throws SchedulerException {
        scheduler.pauseAll();
    }

    /**
     * 暂停某个任务
     *
     * @param name
     * @param group
     * @throws SchedulerException
     */
    public void pauseJob(String name, String group) throws SchedulerException {
        JobKey jobKey = new JobKey(name, group);
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if (jobDetail == null)
            return;
        scheduler.pauseJob(jobKey);
    }

    /**
     * 恢复所有任务
     *
     * @throws SchedulerException
     */
    public void resumeAllJob() throws SchedulerException {
        scheduler.resumeAll();
    }

    /**
     * 恢复某个任务
     *
     * @param name
     * @param group
     * @throws SchedulerException
     */
    public void resumeJob(String name, String group) throws SchedulerException {
        JobKey jobKey = new JobKey(name, group);
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if (jobDetail == null)
            return;
        scheduler.resumeJob(jobKey);
    }

    /**
     * 删除某个任务
     *
     * @param name
     * @param group
     * @throws SchedulerException
     */
    public void deleteJob(String name, String group) throws SchedulerException {
        JobKey jobKey = new JobKey(name, group);
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if (jobDetail == null)
            return;
        scheduler.deleteJob(jobKey);
    }

 /*   private void startJob1(Scheduler scheduler,String name,String startTime) throws SchedulerException {
        // 通过JobBuilder构建JobDetail实例,JobDetail规定只能是实现Job接口的实例
        // JobDetail 是具体Job实例
        JobDetail jobDetail = JobBuilder.newJob(SchedulerQuartzJob1.class).withIdentity(name, "group1").build();
        // 基于表达式构建触发器
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
       // CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(startTime);
        // CronTrigger表达式触发器 继承于Trigger
        // TriggerBuilder 用于构建触发器实例
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(name, "group1")
                .withSchedule(cronScheduleBuilder).build();
        scheduler.scheduleJob(jobDetail, cronTrigger);
    }*/

    private void startJob2(Scheduler scheduler) throws SchedulerException {
        JobDetail jobDetail = JobBuilder.newJob(SchedulerQuartzJob2.class).withIdentity("job2", "group2").build();
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 0/5 * * * ?");
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job2", "group2")
                .withSchedule(cronScheduleBuilder).build();
        scheduler.scheduleJob(jobDetail, cronTrigger);
    }
}
View Code


6编写API

package com.souche.salt_common_01.controller;
import com.souche.salt_common_01.config.QuartzScheduler;
import org.apache.ibatis.annotations.Delete;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;


/**
 * 这里并没有采用restful风格 只是简单封装了一下api
 *
 * @author yvan
 *
 */
@RestController
public class QuartzApiController {
    @Autowired
    private QuartzScheduler quartzScheduler;

    @PostMapping("/lantu/quartz")
    public void startQuartzJob(String name,String startTime) {

        try {
            quartzScheduler.startJob(name,startTime);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/lantu/info")
    public String getQuartzJob(String name, String group) {
        String info = null;
        try {
            info = quartzScheduler.getJobInfo(name, group);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return info;
    }

    @PutMapping("/lantu/modify")
    public void modifyQuartzJob(String name, String startTime) {

        boolean flag = true;
        try {
             quartzScheduler.modifyJob(name, "group1", startTime);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        //return flag;
    }

    @GetMapping (value = "/lantu/pause")
    public void pauseQuartzJob(String name, String group) {
        try {
            quartzScheduler.pauseJob(name, group);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    @GetMapping(value = "/lantu/pauseAll")
    public void pauseAllQuartzJob() {
        try {
            quartzScheduler.pauseAllJob();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    @DeleteMapping(value = "/lantu/delete")
    public void deleteJob(String name, String group) {
        try {
            quartzScheduler.deleteJob(name, group);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

}
View Code

以上就是完成了一个简单的定时任务:并且解决了SchedulerQuartzJob1中不可以注入其他service 的问题。

但是一但项目重启 这些加入内存的定时任务就会丢失。解决办法如下。

7 监听器

对于监听器的使用我并不理解,我只是找了一个解决问题的办法:

每次项目启动的时候 读取数据库中自己存储任务的任务表,把任务重新添加进来。

package com.souche.salt_common_01.config;



import com.souche.salt_common_01.controller.TimeJobController;
import com.souche.salt_common_01.entity.TimeJobs;
import com.souche.salt_common_01.entity.TimeJobsExample;
import com.souche.salt_common_01.mapper.TimeJobsMapper;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;

import java.util.List;

@Configuration
public class ApplicationStartQuartzJobListener implements ApplicationListener<ContextRefreshedEvent>{
    @Autowired
    private QuartzScheduler quartzScheduler;
    @Autowired
    private TimeJobsMapper timeJobsMapper;


/**
     * 初始启动quartz
     */

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        try {

            //读取我的数据库  获得要执行的任务名称 和执行时间,然后添加进去
            TimeJobsExample timeJobsExample=new TimeJobsExample();
            timeJobsExample.or().andStatusEqualTo("running");
            List<TimeJobs> timeJobs=timeJobsMapper.selectByExample(timeJobsExample);
            for (TimeJobs tjob:timeJobs
                 ) {
                   quartzScheduler.startJob(tjob.getId(),tjob.getDoTime());
            }


            System.out.println("任务已经启动...");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


 

}

以上只是我工作中暂时解决定时任务的方法:其中我用到了 添加定时任务,和删除定时任务, 其他api有待测试

猜你喜欢

转载自www.cnblogs.com/hhxylm/p/10592872.html