spring+quartz.2.3.0数据库持久化实现

spring+quartz.2.3.0数据库持久化实现

  • maven 配置
  • sql脚本初始化
  • quartz.properties配置
  • quartz工厂配置
  • 实现一个简单的任务demo
  • 编写一个controller来操作定时任务

我们废话不多说,直接上代码。

maven 配置

第一步我们将需要的jar引入到项目中

 
        <dependency>
            <groupId>org.quartz-schedulergroupId>
            <artifactId>quartzartifactId>
            <version>2.3.0version>
        dependency>
        <dependency>
            <groupId>org.quartz-schedulergroupId>
            <artifactId>quartz-jobsartifactId>
            <version>2.3.0version>
        dependency>

sql脚本初始化

quartz 数据库持久化需要用到11张表。我们需要在数据库中执行mysql的初始化脚本。
mysql 初始化脚本下载

quartz.properties配置

#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName=quartzScheduler
#ID设置为自动获取 每一个必须不同
org.quartz.scheduler.instanceId = AUTO
#远程管理相关的配置,全部关闭
org.quartz.scheduler.rmi.export= false
org.quartz.scheduler.rmi.proxy= false
org.quartz.scheduler.wrapJobExecutionInUserTransaction=false
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
#线程数量
org.quartz.threadPool.threadCount=15
#线程优先级
org.quartz.threadPool.threadPriority=5
#自创建父线程
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
#容许的最大作业延
org.quartz.jobStore.misfireThreshold= 60000
#持久化配置
#数据保存方式为持久化
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties=true
#加入集群
org.quartz.jobStore.isClustered = false  

#数据库表前缀
org.quartz.jobStore.tablePrefix=QRTZ_
#调度实例失效的检查时间间隔
org.quartz.jobStore.clusterCheckinInterval = 20000
# jobStore处理未按时触发的Job的数量
org.quartz.jobStore.maxMisfiresToHandleAtATime=20

quartz工厂配置

@Configuration
@Data
public class QuartzConfig {
    public static final String QUARTZ_PROPERTIES_PATH = "/quartz.properties";
    @Resource
    private DataSource dataSource;
    @Resource
    private PlatformTransactionManager transactionManager;
    @Resource
    private ApplicationContext applicationContext;
    @Bean(name = "jobFactory")
    public JobFactory jobFactory(ApplicationContext applicationContext) {
        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
        jobFactory.setApplicationContext(applicationContext);
        return jobFactory;
    }
   @Bean (name = "schedulerFactoryBean")
    public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setJobFactory(jobFactory(applicationContext));
        factory.setQuartzProperties(quartzProperties());
        factory.setOverwriteExistingJobs(true); //每次启动都更新job信息
        factory.setDataSource(dataSource);//jdbc store
        factory.setStartupDelay(30);// QuartzScheduler 延时启动,应用启动完30秒后 QuartzScheduler 再启动
        factory.setAutoStartup(true);
        factory.setTransactionManager(transactionManager);
        return factory;
    }

    /**
     * quartz 初始化监听器
     * @return
     */
    @Bean
    public QuartzInitializerListener initializerListener(){
        return  new QuartzInitializerListener();
    }
    @Bean
    public Properties quartzProperties() throws IOException {
        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
        propertiesFactoryBean.setLocation(new ClassPathResource(QUARTZ_PROPERTIES_PATH));
        propertiesFactoryBean.afterPropertiesSet();
        return propertiesFactoryBean.getObject();
    }
    /**
     * 通过SchedulerFactoryBean获取Scheduler的实例
     */
    public static class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements
            ApplicationContextAware {

        private transient AutowireCapableBeanFactory beanFactory;

        @Override
        public void setApplicationContext(final ApplicationContext context) {
            beanFactory = context.getAutowireCapableBeanFactory();
        }

        @Override
        protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
            final Object job = super.createJobInstance(bundle);
            beanFactory.autowireBean(job);
            return job;
        }
    }
}

实现一个简单的任务demo

public class SayHelloJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) 
    throws JobExecutionException {
    		//todo
    		System.out.println("Hello word!");
    }
}

编写一个controller来操作定时任务

@Controller
@RequestMapping("/quartz")
public class InitQuartzController {
    @Autowired
    private SchedulerFactoryBean schedulerFactoryBean;
    private static final String TRIGGER_GROUP_NAME="group1";
    private static final String JOB_GROUP_NAME="group1";
    /**
    * 初始化定时任务
    */
    @RequestMapping("/init")
    @ResponseBody
    @Authorization
    public String scheduleJobs() throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobDetail jobDetail = JobBuilder.newJob(SayHelloJob.class)
                .withDescription("sayHello定时任务")
                .withIdentity("SayHelloJob", JOB_GROUP_NAME)
                .build();
        Trigger trigger = TriggerBuilder.newTrigger()
                .forJob(jobDetail)
                .withSchedule(cronSchedule("0 10 7 * * ?"))
                .build();
        if(!scheduler.checkExists(JobKey.jobKey("AddArticleReadRecordJob","group1"))){
            scheduler.scheduleJob(jobDetail,trigger);
        }
        scheduler.start();
        return "add success";
    }

    /**
     *
     * @param jobJava
     * @param jobDesc
     * @param jobName
     * @param group
     * @param cron
     * @return
     */
    @RequestMapping("/add")
    @ResponseBody
    @Authorization //权限验证,非必须
    public String addJob(String jobJava,String jobDesc,String jobName, @RequestParam(name = "group",defaultValue = "group1")String group,
                         @RequestParam(name = "cron") String cron) throws SchedulerException, ClassNotFoundException {
        Class jobClass=Class.forName(jobJava);
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobDetail jobDetail = JobBuilder.newJob(jobClass)
                .withDescription(jobDesc)
                .withIdentity(jobName, group)
                .build();
        Trigger trigger = TriggerBuilder.newTrigger()
                .forJob(jobDetail)
                .withSchedule(cronSchedule(cron))
                .build();
        if(!scheduler.checkExists(JobKey.jobKey(jobName,group))){
            scheduler.scheduleJob(jobDetail,trigger);
        }
        scheduler.start();
        return "添加成功";
    }
    @RequestMapping(value = "/resumeJob",method = RequestMethod.GET)
    @ResponseBody
    @Authorization
    public String resumeJob(String jobName, String jobGroup) throws SchedulerException {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobKey jobKey=JobKey.jobKey(jobName,jobGroup);
        List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
        //将trigger表中的state重置
        triggers.forEach(x->{
            try {
                scheduler.resetTriggerFromErrorState(x.getKey());
            } catch (SchedulerException e) {
                Logs.error("重置定时任务异常:"+e.getMessage(),e);
            }
        });
        scheduler.resumeJob(jobKey);
        return "success";
    }

    /**
     * 删除一个定时任务
     * @return
     */
    @ResponseBody
    @RequestMapping("/removeJob")
    @Authorization
    public String removeJob(String jobName,String jobGroupName) throws SchedulerException {
        Scheduler scheduler=schedulerFactoryBean.getScheduler();
        TriggerKey tiger= new TriggerKey(jobName,TRIGGER_GROUP_NAME);
        scheduler.pauseTrigger(tiger);
        scheduler.unscheduleJob(tiger);
        scheduler.deleteJob(new JobKey(jobName,jobGroupName));
        return "success";
    }

    /**
     * 修改定时任务执行时间表达式
     * @param jobName
     * @param jobGroupName
     * @param triggerName
     * @param triggerGroupName
     * @param cron
     * @return
     */
    @ResponseBody
    @RequestMapping("/modifyJob")
    @Authorization
    public String modifyJob(String jobName,String jobGroupName,String triggerName,String triggerGroupName,String cron){
        try {
            Logs.info("jobName="+jobName+"; jobGroupName="+jobGroupName+"; triggerName="+triggerName+"; triggerGroupName="+triggerGroupName+"; cron="+cron);
            TriggerKey triggerKey =null;
            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            if(StringUtils.hasText(triggerName)||StringUtils.hasText(triggerGroupName)){
                triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
            }else {
                //通过任务名称和任务主修改
                List<? extends Trigger>triggers= scheduler.getTriggersOfJob(JobKey.jobKey(jobName,jobGroupName));
                if(triggers!=null&&triggers.size()>0){
                    triggerKey=triggers.get(0).getKey();
                }
            }
            Logs.info("triggerName= "+triggerKey.getName()+"; triggerGroupName="+triggerKey.getGroup());
            CronTrigger cronTrigger= (CronTrigger) scheduler.getTrigger(triggerKey);
            if(cronTrigger==null){
                return "定时任务出发时间为空!更新失败";
            }
            String oldTime=cronTrigger.getCronExpression();
            if(!oldTime.equals(cron)){//判断表达式是否一致,如果一致则不需要修改
                TriggerBuilder<Trigger> triggerBuilder=TriggerBuilder.newTrigger();
                triggerBuilder.withIdentity(triggerKey.getName(),triggerKey.getGroup());
                triggerBuilder.startNow();
                //触发器设定
                triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
                // 创建Trigger对象
                cronTrigger = (CronTrigger) triggerBuilder.build();
                scheduler.resumeTrigger(triggerKey);
                scheduler.rescheduleJob(triggerKey,cronTrigger);
            }
        }catch (Exception e){
            Logs.error("修改定时任务异常:"+e.getMessage(),e);
            return "failed";
        }
        return "success";
    }

}

你可能感兴趣的:(java)