精华内容
下载资源
问答
  • Quartz定时框架

    2019-06-19 16:35:45
    package ... import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; import org.quartz.JobExecutionContext; //防止单个job并行 @DisallowConcurrentExecution public class Ins...
    package com.sinosoft.cn.main;
    
    
    import org.quartz.DisallowConcurrentExecution;
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    
    //防止单个job并行
    @DisallowConcurrentExecution
    public class InserPolicyInfoQuartz implements Job {
        public void execute(JobExecutionContext context) {
    
            //具体业务逻辑
            InserPolicyInfo ipi = new InserPolicyInfo();
            ipi.savePolicyInfo();
    
    
        }
    }

     

    package com.sinosoft.cn.main;
    
    import static org.quartz.CronScheduleBuilder.cronSchedule;
    
    import org.quartz.JobBuilder;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerFactory;
    import org.quartz.Trigger;
    import org.quartz.TriggerBuilder;
    import org.quartz.impl.StdSchedulerFactory;
    
    public class QuartzTest {
        public static void main(String[] args) {
    
            //创建工厂scheduler
            SchedulerFactory schedulerfactory = new StdSchedulerFactory();
            Scheduler scheduler = null;
    
            try {
                // 通过schedulerFactory获取一个调度器
                scheduler = schedulerfactory.getScheduler();
    
                // 指明job的名称,所在组的名称,以及绑定job类
                JobDetail job = JobBuilder.newJob(InserPolicyInfoQuartz.class).withIdentity("JobName", "JobGroupName").usingJobData("name", "quartz").build();
    
                //定义一个Trigger(规定 每天0点8点16点各运行一次)
                Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1") //定义name/group
                        .withSchedule(cronSchedule("0 0/5 * * * ?"))
    //                .withSchedule(cronSchedule("0 0/1 9-23 * * ?"))
                        // .withSchedule(cronSchedule("0 0 0,8,16 * * ?"))
                        .startNow()
                        .build();
                // 把作业和触发器注册到任务调度中
                scheduler.scheduleJob(job, trigger);
    
                // 启动调度
                scheduler.start();
    
                //运行一段时间后关闭
    //            Thread.sleep(10000);
    //            scheduler.shutdown(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    展开全文
  • Quartz定时框架的持久化

    千次阅读 2018-09-17 21:13:06
    小强的上一篇quartz文章简单的说了一下quartz的怎样使用,一般在实际工作中那个根本是不够的,所以今天在这记录下Quartz定时框架的持久化, 一、quartz的存储于持久化介绍 Quartz框架有两种任务存储方式。一种...
    小强的上一篇quartz文章简单的说了一下quartz的怎样使用,一般在实际工作中那个根本是不够的,所以今天在这记录下Quartz定时框架的持久化,

    一、quartz的存储于持久化介绍

    Quartz框架有两种任务存储方式。一种是RAMJobStore存储方式,也是默认的存储方式。RAMJobStore将quartz定时的任务信息存储在服务器的内存中,这种方式的优点是可以提供最好的性能,因为任务信息都存储在内存中访问获取数据速度快。缺点是当服务器突然崩溃了再次重启后你的定时任务也就没有了。另一种是JDBC任务(作业)存储方式,这种方式是将任务信息存储在数据库中,当服务器突然崩溃了再次重启后你的任务还是会接着上次继续执行的,不过需要配置一个quartz.propertity的配置文件(后面会讲到)。
    例如:设置了一个50次的的任务当执行了20次后服务器崩溃了,如果采用RAMJobStore存储方式那么在重启后你的定时任务也就没有了,如需执行那就得重新设置50次的定时任务,如果采用了JDBC任务存储的方式那么在你服务器重启后你可以不用重新设置你的定时任务,因为你的定时任务存储在服务器中可以继续接着运行第21次、22次...这就是任务的持久化。

    二、持久化示例

    从下载的压缩包包中找到你是所使用数据库对应的.sql文件也就是所需要的各种表一般表的地址都在 quartz-2.2.3\docs\dbTables中.(注意你需要将sql文件里的数据库名字改成你自己的库名,至于怎样找到库名可以打开sql文件翻译一下最上面的注释)

    在这里解释一下每个表所对应的意思,字段名字太多就不写了可以自己百度一下
    表名 含义
    QRTZ_BLOB_TRIGGERS 以Blob 类型存储的触发器
    QRTZ_CALENDARS 存放日历信息, quartz可配置一个日历来指定一个时间范围
    QRTZ_CRON_TRIGGERS 存放cron类型的触发器。
    QRTZ_FIRED_TRIGGERS 存放已触发的触发器
    QRTZ_JOB_DETAILS 存放一个jobDetail信息
    QRTZ_LOCKS 存储程序的悲观锁的信息(假如使用了悲观锁)
    QRTZ_PAUSED_TRIGGER_GRPS 存放暂停掉的触发器
    QRTZ_SCHEDULER_STATE 调度器状态
    QRTZ_SIMPLE_TRIGGERS 简单触发器的信息
    QRTZ_TRIGGERS 触发器的基本信息

    2、 quartz.properties配置文件

    先贴出我的配置文件然后在解释
     # Default Properties file for use by StdSchedulerFactory  
        # to create a Quartz Scheduler Instance, if a different  
        # properties file is not explicitly specified.  
        
        #集群配置  
        
        org.quartz.scheduler.instanceName: Mscheduler
        org.quartz.scheduler.instanceId = AUTO      
        org.quartz.scheduler.rmi.export: false  
        org.quartz.scheduler.rmi.proxy: false  
        org.quartz.scheduler.wrapJobExecutionInUserTransaction: false  
           
        org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool  
        org.quartz.threadPool.threadCount: 3  
        org.quartz.threadPool.threadPriority: 5  
        org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true  
           
        #============================================================================  
        # Configure JobStore  
        #============================================================================  
           
        org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX  
        org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.MSSQLDelegate  
        org.quartz.jobStore.useProperties:false  
        org.quartz.jobStore.isClustered = false 
        org.quartz.jobStore.tablePrefix = QRTZ_    
        org.quartz.jobStore.dataSource:mySqlServer 
        org.quartz.jobStore.maxMisfiresToHandleAtATime=1 
        org.quartz.jobStore.misfireThreshold: 60000  
        org.quartz.jobStore.clusterCheckinInterval:20000       
           
        #============================================================================  
        # Configure Datasources  
        #============================================================================   
    	org.quartz.dataSource.mySqlServer.driver = com.microsoft.sqlserver.jdbc.SQLServerDriver
    	org.quartz.dataSource.mySqlServer.URL = jdbc:sqlserver://localhost:1433;DatabaseName=test;SelectMethod=cursor
    	org.quartz.dataSource.mySqlServer.user = sa	
    	org.quartz.dataSource.mySqlServer.password = 123456
    	org.quartz.dataSource.mySqlServer.maxConnections = 10
    	org.quartz.dataSource.mySqlServer.validationQuery=select count(0) from
    

    Quartz的属性配置文件主要包括三方面的信息:
    1)集群信息;
    2)调度器线程池;
    3)任务调度现场数据的保存。

    集群信息:
    (1) org.quartz.scheduler.instanceName: Mscheduler 表示调度器的实例名,可以是任何字符串。用来在用到多个调度器区分特定的调度器实例
    (2) org.quartz.scheduler.instanceId = AUTO 表示调度器的实例ID在所有调度器实例中必须是唯一的同样也可以是任何字符串,AUTO代表是Quartz框架自动帮你生成

    调度器线程池;
    (1)org.quartz.threadPool.class:org.quartz.simpl.SimpleThreadPool 表示线程池的实现类(一般使用 SimpleThreadPool即可满足几乎所有用户的需求)
    (2) org.quartz.threadPool.threadCount: 3 指定线程数量,至少为1(无默认值)
    (3)org.quartz.threadPool.threadPriority:5 设置线程的优先级(最大为java.lang.Thread.MAX_PRIORITY10,最小为Thread.MIN_PRIORITY 1,默认为5)
    (4)org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true 是否自创建父线程

    任务存储设置
    (1)org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX 调度器信息存储设置在这是存储在数据库( org.quartz.simpl.RAMJobStore为存储在内存中)
    (2) org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.MSSQLDelegate 数据库平台类似于Hibernate的dialect,用于处理DB之间的差异(每种数据库都是不同,后边会写出来)
    (3) org.quartz.jobStore.useProperties:false 设置TRUE不会出现序列化非字符串类到 BLOB 时产生的类版本问题
    (4)org.quartz.jobStore.isClustered = false 是否加入集群
    (5) org.quartz.jobStore.tablePrefix = QRTZ_ 设置表的前缀(默认QRTZ_)
    (6)org.quartz.jobStore.dataSource:mySqlServer 数据库别名 随便取
    (7)org.quartz.jobStore.maxMisfiresToHandleAtATime=1 jobStore处理未按时触发的Job的数量
    (8)org.quartz.jobStore.misfireThreshold: 60000 容许的最大作业延长时间
    (9)org.quartz.jobStore.clusterCheckinInterval:20000 调度实例失效的检查时间间隔

    数据库配置信息(这个就不一一解释了)
    (1)org.quartz.dataSource.mySqlServer.driver = com.microsoft.sqlserver.jdbc.SQLServerDriver
    (2)org.quartz.dataSource.mySqlServer.URL = jdbc:sqlserver://localhost:1433;DatabaseName=test;SelectMethod=cursor
    (3)org.quartz.dataSource.mySqlServer.user = sa
    (4)org.quartz.dataSource.mySqlServer.password = 123456
    (5)org.quartz.dataSource.mySqlServer.maxConnections = 10 连接池中最大连接数
    (6org.quartz.dataSource.mySqlServer.validationQuery=select count(0) from) 设置加锁的SQL语句


    org.quartz.jobStore.driverDelegateClass数据库平台

    在这里插入图片描述

    3、main方法执行类

    package quartz;
    
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    import org.quartz.CronScheduleBuilder;
    import org.quartz.DateBuilder;
    import org.quartz.JobBuilder;
    import org.quartz.JobDetail;
    import org.quartz.JobKey;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.SchedulerFactory;
    import org.quartz.SimpleScheduleBuilder;
    import org.quartz.SimpleTrigger;
    import org.quartz.Trigger;
    import org.quartz.TriggerBuilder;
    import org.quartz.TriggerKey;
    import org.quartz.impl.StdSchedulerFactory;
    
    public class ScheduleMain {
    	public static void main(String[] args) throws SchedulerException {
    		resumeJob();
    		//addJob();
    	}	
    	//添加一个任务
    	public static void addJob() throws SchedulerException {
    
    		// 通过 schedulerFactory 获取一个调度器
    		SchedulerFactory sf = new StdSchedulerFactory();
    		Scheduler scheduler = sf.getScheduler();
    		
    		// 创建 jobDetail 实例,绑定 Job 实现类
            // 指明 job 的名称,所在组的名称,以及绑定 job 类
    		JobDetail job = JobBuilder.newJob(TimerJob.class).withIdentity("Job7","group2").build();
    		
    		// 定义调度触发规则
            // (1)SimpleTrigger,从当前时间的下 1 秒开始,每隔 1 秒执行 1 次,重复执行 2 次
    		//TriggerBuilder<SimpleTrigger> trigger = TriggerBuilder.newTrigger()
    //				Trigger trigger = (Trigger) TriggerBuilder.newTrigger()
    //					// 指明 trigger 的 name 和 group
    //					.withIdentity("trigger4", "group1")
    //					// 从当前时间的下 1 秒开始执行,默认为立即开始执行(.startNow())
    //					.startNow()
    //					.startAt(DateBuilder.evenSecondDate(new Date()))
    //					.withSchedule(SimpleScheduleBuilder.simpleSchedule()
    //					.withIntervalInSeconds(5) // 每隔 1 秒执行 1 次
    //					.withRepeatCount(50)) // 重复执行 2 次,一共执行 3 次
    //					.build();
    		//(2)corn 表达式,先立即执行一次,然后每隔 5 秒执行 1 次
    		Trigger trigger = (Trigger) TriggerBuilder.newTrigger()
    				.withIdentity("trigger7","group2")
    				.withSchedule(CronScheduleBuilder.cronSchedule("0/1 * * * * ?"))//[秒] [分] [时] [每月的第几日] [月] [每周的第几日] [年]
    				.build();
    		  // 初始化参数传递到 job
    		job.getJobDataMap().put("myDescription", "come on");
    		job.getJobDataMap().put("myValue", 1990);
    		List<String> list = new ArrayList<>();
    	        list.add("firstItem");
    	    job.getJobDataMap().put("myArray", list);
    	    
    	    // 把作业和触发器注册到任务调度中
    	    scheduler.scheduleJob(job,trigger);
    	    
    	    // 启动计划程序(实际上直到调度器已经启动才会开始运行)
    	    scheduler.start();
    
            try {
    			Thread.sleep(10000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    
            // 等待作业执行完成时才关闭调度器
            //scheduler.shutdown(true);
    	}
    	//从数据库中找到已经存在的job,并重新开户调度 
    	public static void resumeJob() {
    		try {  
                SchedulerFactory schedulerFactory = new StdSchedulerFactory();  
                Scheduler scheduler = schedulerFactory.getScheduler();  
                //获取调度器中所有的触发器组  
                List<String> triggerGroups = scheduler.getTriggerGroupNames();  
                //遍历获取每个触发器组
                for (int i = 0; i < triggerGroups.size(); i++) { 
                    List<String> triggers = scheduler.getTriggerGroupNames();  
                    //遍历每个触发器组 
                    for (int j = 0; j < triggers.size(); j++) {  \
    	            //获取每个触发器
                        Trigger tg = scheduler.getTrigger(new TriggerKey(triggers  
                                .get(j), triggerGroups.get(i)));  
                        // 重新恢复在tgroup1组中,名为trigger1_1触发器的运行 
                        if (tg instanceof SimpleTrigger  
                                && tg.getDescription().equals("group1.trigger1")) {  
                            //恢复运行  
                            scheduler.resumeJob(new JobKey(triggers.get(j),  
                                    triggerGroups.get(i)));  
                        }  
                    }  
      
                }  
                scheduler.start();  
            } catch (Exception e) {  
                e.printStackTrace();  
      
            } 
    	}
    }
    
    

    4、Job任务类

    package quartz;
    
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    
    import org.quartz.Job;
    import org.quartz.JobDataMap;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    
    /*
     * 
     * 定义需要执行的任务。该类是一个接口,只定义一个方法 execute(JobExecutionContext context)
    	在实现类的 execute 方法中编写所需要定时执行的 Job(任务), JobExecutionContext 类提供了调度应用的一些信息。
    	Job 运行时的信息保存在 JobDataMap 实例中。
     */
    public class TimerJob implements Job {
    
    	@Override
    	public void execute(JobExecutionContext context) throws JobExecutionException {
    		// 从 context 中获取 instName, groupName 以及 dataMap
    		String insName = context.getJobDetail().getKey().getName();
    		String groupName = context.getJobDetail().getKey().getGroup();
    		JobDataMap dataMap = context.getJobDetail().getJobDataMap();
    		
    		 // 从 dataMap 中获取 myDescription, myValue 以及 myArray
    		String myDescription = dataMap.getString("myDescription");
    		int myValue = dataMap.getInt("myValue");
    		List<String> myArray = (List<String>)dataMap.get("myArray");
    		//打印JobDetail和JobDataMap的信息
    		System.out.println("---> Instance = " + insName + ", group = " + groupName+", description = " 
    				+ myDescription + ", value =" + myValue+" , array item[0] = " + myArray.get(0));
    
    	}
    }
    

    5、执行结果

    执行结果

    三、结尾

    好了,这就是quartz框架的持久化,在这个过程中会遇到好多问题及困难。但是请记住千万不要气馁只要死磕下去你就会成功的。小强会在下一篇中说说quartz任务的动态增删改查以及在学习quartz中遇到的问题及怎样解决。如有兴趣请给个关注点个赞,也算给小强一点激励吧毕竟一个人还是很孤单的。

    上一篇 Quartz定时框架

    下一篇 Quartz定时任务动态增删改查

    本文属于原创如有转载请标明原文链接:https://blog.csdn.net/little__SuperMan/article/details/82749103

    展开全文
  • -- quartz定时框架 --&gt; &lt;dependency&gt; &lt;groupId&gt;org.quartz-scheduler&lt;/groupId&gt; &lt;artifactId&gt;quartz&lt;/artifactId&gt; &lt;...

    1.导包

    <!-- quartz定时框架 -->
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.3.0</version>
    </dependency>

    2.配置spring-job文件

    <!--配置定时刷新微信的目标类-->
    <bean id="wxAccessTokenJob" class="com.xhh.wyzc.wx.job.WxAccessTokenJob"/>
    <!-- 定时刷新微信 accessToken-->
    <bean id="cronJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <!-- 执行目标job -->
        <property name="targetObject" ref="wxAccessTokenJob"/>
        <!-- 执行的方法 -->
        <property name="targetMethod" value="refreshAccessToken" />
    </bean>
    <!--配置定时触发器-->
    <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="cronJobDetail"/>
        <!--每隔30分钟执行一次-->
        <property name="cronExpression" value="0 0/30 * * * ?"/>
    </bean>
    <!--配置调度器工厂-->
    <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <!--配置触发器-->
        <property name="triggers">
            <list>
                <ref bean="cronTrigger"/>
            </list>
        </property>
    </bean>

    3.job处理类

    public class WxAccessTokenJob{
        protected static final String WX_ACCESS_TOKEN = "WX_ACCESS_TOKEN";
        protected static final String WX_ACCESS_TOKEN_GEN_TIME = "WX_ACCESS_TOKEN_GEN_TIME";
        private final Logger logger = LoggerFactory.getLogger(this.getClass());
        private static int times = 0;
        @Autowired
        private ConfigDao configDao;
    
        /**
         * 定时刷新微信accessToken
         * @throws JobExecutionException
         */
        public void refreshAccessToken(){
            Config accessTokenConfig = configDao.selectByKey(WX_ACCESS_TOKEN);
            String accessToken = accessTokenConfig.getCvalue();
            Config accessTokenGenTimeConfig = configDao.selectByKey(WX_ACCESS_TOKEN_GEN_TIME);
            String accessTokenGenTime = accessTokenGenTimeConfig.getCvalue();
            Long now = new Date().getTime();
            accessToken = ApiTool.getAccessToken(SysInfo.CONFIG.get("WX_APPID"),SysInfo.CONFIG.get("WX_SECRET"));
            updateWxAccessToken(WX_ACCESS_TOKEN, accessToken);
            updateWxAccessToken(WX_ACCESS_TOKEN_GEN_TIME, now.toString());
            logger.info("-----accessToken刷新:" + accessToken + "-----");
            System.out.println(""+times+++"次执行任务");
        }

    展开全文
  • 这篇是学习SpringBoot的第七篇文章,这篇记录的是Quartz定时框架的使用。本次项目的工程还是延用这之前创建的firstproject工程。 SpringBoot本身有一个定时任务的框架,但是Task也有不足之处。想动态的执行定时...

    目录

    一、前言

    二、开启Quartz之旅

    2.1 Quartz框架介绍

    2.2 从一个简单的demo开始

    2.3Quartz框架中Job依赖注入service,实现数据库操作

    2.4Quartz的API

    三、感谢


    一、前言

        这篇是学习SpringBoot的第七篇文章,这篇记录的是Quartz定时框架的使用。本次项目的工程还是延用这之前创建的firstproject工程。

        SpringBoot本身有一个定时任务的框架,但是Task也有不足之处。想动态的执行定时任务就比较困难。这就体现出了quartz的优势,它很容易的管理定时任务,很容易动态的操作定时任务。

        Quartz有三个核心概念:调度器、任务和触发器。三者关系是,调度器负责调度各个任务,到了某个时刻或者过了一定时间,触发器触动了,特定任务便启动执行。

        这边文章相对较长,主要分为4个部分,第一部分是介绍quartz框架,第二部分是使用框架做一个简单的例子,第三部分是能够进行数据库操作,第四部分是能够动态的操作任务的执行。便于大家寻找我i将每部分的标题飘上了橘黄色

    二、开启Quartz之旅

    2.1 Quartz框架介绍

    Quartz框架有几大核心组件:
    1.Scheduler任务调度
        是Quartz最核心的概念,需要把JobDetail和Trigger注册到scheduler中,才可以执行。
        使触发器及任务关联起来。(后面的代码中有详细的上下文)

    scheduler.scheduleJob(jobDetail, cronTrigger);

    2.Job任务,JobExecutionContext类提供调度上下文的各种信息
    其实Job是接口,任务类要实现Job接口,重写Job接口的execute方法。
    任务类还可以使用以下三个注解进行修饰:
    @DisallowConcurrentExecution:此注解表示不允许这个Job并发执行

    @PersistJobDataAfterExecution:此注解表示当这个Job的execute方法执行成功后,更新并存储它所持有的JobDetail属性中JobDataMap。如果使用这个注解,建议也使用@DisallowConcurrentExecution,因为并发执行过程中,JobDataMap有可能会发生冲突。

    3.Trigger触发器/TruggerBuilder(创建Trigger)/ThreadPool(线程)
    执行任务的规则;比如每天,每小时等。
    一般情况使用SimpleTrigger,和CronTrigger,这些触发器实现了Trigger接口。SimpleScheduleBuilder和CronScheduleBuilder继承ScheduleBuilder抽象类 。

    对于简单的时间来说,比如每天执行几次,使用SimpleTrigger。
    对于复杂的时间表达式来说,比如每个月15日上午几点几分,使用CronTrigger以及CromExpression 类。

    Priority:这个属性表示Trigger的权重。当两个Trigger触发时间相同时,权重大的那个先执行。Quartz默认的权重值为5。
    Misfire Instruction:在Trigger接口中可以设置错过触发处理机制

    4.JobDetail任务细节/JobBuilder(创建JobDetail)/JobStore保存Job数据:保存内存或数据库中)/JobDataMap:JSON数据格式
    任务细节,Quartz执行Job时,需要新建个Job实例,但是不能直接操作Job类,所以通过JobDetail来获取Job的名称、描述信息。
    调度器作为作业的总指挥,触发器作为作业的操作者,作业为应用的功能模块。
    JobDetail有两个boolean属性。
    isDurable:如果设为false,则对应的Job一旦没有关联的触发器,就会被Scheduler自动删除。 requestsRecovery:如果设为true,当Job执行中遇到硬中断(例如运行崩溃、机器断电等),Scheduler会重新执行。这种情况下,
    JobExecutionContext.isRecovering()会返回ture。

    5.Calendar(排除某个任务不执行)
    一个Trigger可以和多个Calendar关联

    6.监听器JobListener TriggerListener SchedulerListener

    7.JobKey 和 TriggerKey
    在Quartz中,可以分别通过JobKey和TriggerKey来唯一地识别一个Job或一个Trigger。
    这两个Key都有两个关键属性:name和group。

    2.2 从一个简单的demo开始

    2.2.1 编写任务类,实现Job接口。我这里编写了两个任务类

        Job1

    package com.xuexue.firstproject.Quartz;
    
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    public class QuartzJob1 implements Job {
        private void before(){
            System.out.println("QuartzJob1 任务开始执行");
        }
    
        @Override
        public void execute(JobExecutionContext arg0) throws JobExecutionException {
            before();
            System.out.println("开始:"+System.currentTimeMillis());
            // TODO 业务
            System.out.println("结束:"+System.currentTimeMillis());
            after();
        }
    
        private void after(){
            System.out.println("QuartzJob1 任务结束执行");
        }
    
    }

    Job2

    package com.xuexue.firstproject.Quartz;
    
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    
    public class QuartzJob2 implements Job {
    
        private void before(){
            System.out.println("QuartzJob2任务开始执行");
        }
    
        @Override
        public void execute(JobExecutionContext arg0) throws JobExecutionException {
            before();
            System.out.println("开始:"+System.currentTimeMillis());
            // TODO 业务
            System.out.println("结束:"+System.currentTimeMillis());
            after();
        }
    
        private void after(){
            System.out.println("QuartzJob2任务结束执行");
        }
    }
    

    2.2.2编写任务调度和处理的类.

        Schedule提供了几个操作任务的方法

        scheduler.start():开启job

        scheduler.scheduleJob(jobDetail, cronTrigger):再容器中使触发器和任务关联

        scheduler.pauseAll():暂停所有任务

        scheduler.pauseJob(jobKey):暂停一个任务

        scheduler.resumeAll():恢复所有任务

        scheduler.resumeJob(jobKey):恢复一个任务

        scheduler.deleteJob(jobKey):从容器中删除一个任务

    以下是任务调度和处理的类的代码:

    package com.xuexue.firstproject.Quartz;
    
    import org.quartz.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.Date;
    
    @Configuration
    public class QuartzJobScheduler {
        // 任务调度
        @Autowired
        private Scheduler scheduler;
    
        /**
         * 开始执行所有任务
         */
        public void startJob() throws SchedulerException {
            startJob1(scheduler);
            startJob2(scheduler);
            scheduler.start();
        }
    
        /**
         * 将job1添加到容器中
         */
        private void startJob1(Scheduler scheduler) throws SchedulerException {
            // 通过JobBuilder构建JobDetail实例,JobDetail规定只能是实现Job接口的实例
            // JobDetail 是具体Job实例
            JobDetail jobDetail = JobBuilder.newJob(QuartzJob1.class).withIdentity("job1", "group1").build();
            // 基于表达式构建触发器
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
            // CronTrigger表达式触发器 继承于Trigger
            // TriggerBuilder 用于构建触发器实例
            CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job1", "group1")
                    .withSchedule(cronScheduleBuilder).build();
            scheduler.scheduleJob(jobDetail, cronTrigger);
        }
    
        /**
         * 将job2添加到容器中
         */
        private void startJob2(Scheduler scheduler) throws SchedulerException {
            JobDetail jobDetail = JobBuilder.newJob(QuartzJob2.class).withIdentity("job2", "group2").build();
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 0/1 * * * ?");
            CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job2", "group2")
                    .withSchedule(cronScheduleBuilder).build();
            scheduler.scheduleJob(jobDetail, cronTrigger);
        }
    
        /**
         * 修改某个任务的执行时间
         */
        public boolean modifyJob(String name, String group, String time) throws SchedulerException {
            Date date = null;
            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;
        }
    
        /**
         *  获取job信息
         */
        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());
        }
    
        /**
         * 暂停所有任务
         */
        public void pauseAllJob() throws SchedulerException {
            scheduler.pauseAll();
        }
    
        /**
         *暂停一个任务
         */
        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);
        }
    
        /**
         * 恢复所有任务
         */
        public void resumeAllJob() throws SchedulerException {
            scheduler.resumeAll();
        }
    
        /**
         * 恢复某个任务
         */
        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);
        }
    
        /**
         *删除一个任务(从任务列表中删除)
         */
        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);
        }
    
        
    
    }
    

    2.2.3编写ApplicationStartQuartzJobListener类,采用监听spring容器加载完毕后事件,启动任务调用;并将Scheduler交给spring初始化管理。

    package com.xuexue.firstproject.Quartz;
    
    import org.quartz.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.ApplicationListener;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.event.ContextRefreshedEvent;
    
    @Configuration
    public class ApplicationStartQuartzJobListener implements ApplicationListener<ContextRefreshedEvent>{
        @Autowired
        private QuartzJobScheduler quartzJobScheduler;
    
    
        @Override
        public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent)  {
            try {
                //启动任务
                quartzJobScheduler.startJob();
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
    
        }
    
        /**
         * 初始注入scheduler
         */
        @Bean
        public Scheduler scheduler() throws SchedulerException{
            SchedulerFactory schedulerFactoryBean = new StdSchedulerFactory();
            return schedulerFactoryBean.getScheduler();
        }
    
    
    
    
    }

    2.2.4编译,启动,就会看到控制台输出定时任务打印的内容

        至此,一个简单的Quartz定时任务框架demo就结束了。接下来要再此基础上丰富一下,我们上面的例子并没有进行数据库操作,但是再实际开发中,在任务中进行数据库操作时必不可免的。下面我们进行数据库的操作。

    2.3Quartz框架中Job依赖注入service,实现数据库操作

    2.3.1我们再写一个任务类job3(ps:不用过多关注我的LxJobInfoService 里面都写了什么了,你可以自己随意写一个从数据库中取数据的方法,然后控制台输出一下,方便验证。我的这个方法时获取job的list集合,后面会有体现)

    package com.xuexue.firstproject.Quartz;
    
    import com.xuexue.firstproject.Services.imp.LxJobInfoService;
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.springframework.beans.factory.annotation.Autowired;
    
    public class QuartzJob3 implements Job {
        @Autowired
        private LxJobInfoService lxJobInfoService;
        @Override
        public void execute(JobExecutionContext jobExecutionContext)  {
                String cron= lxJobInfoService.getJobList().get(0).getJobCron();
                System.out.println("job3  "+cron);
    
        }
    }

    2.3.2将QuartzJobScheduler 类进行修改,添加startJob3()方法,并修改startJob()方法,修改后及新增后的方法如下;

        /**
         * 开始执行所有任务
         */
        public void startJob() throws SchedulerException {
            //startJob1(scheduler);  
            //startJob2(scheduler);
            startJob3(scheduler);
            scheduler.start();
        }
    
        /**
         *将job3添加到容器中
         */
        private void startJob3(Scheduler scheduler) throws SchedulerException {
            JobDetail jobDetail = JobBuilder.newJob(QuartzJob3.class).withIdentity("job3", "group3").build();
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
            CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job3", "group3")
                    .withSchedule(cronScheduleBuilder).build();
            scheduler.scheduleJob(jobDetail, cronTrigger);
        }

    2.3.3这样我们先试着执行一下,会发现,项目报 空指针异常。debug发现在任务中使用的service不能注入的,获取的对象为Null。

    上网查找了一些资料,发现出现这个问题的原因:

        在quartz框架中,Job 是通过反射出来的实例,不受spring的管理,所以就导致注入失败。Scheduler现在交给Spring生成,在Spirng-context-support  jar包下org.springframework.scheduling.quartz包中有个SpringBeanJobFactory的类,job实例通过该类的createJobInstance方法创建。但是创建的job实例并没被spring管理,我们需要重写SpringBeanJobFactory类中的createJobInstance方法,将创建的job实例交给spring管理。接下来我们再写两个类来解决这个问题。

    2.3.4定义MyJobFactory创建Quartz实例

    package com.xuexue.firstproject.Quartz;
    
    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;
    
        }
    }

    2.3.5启动类注入MyJobFactory和Scheduler

    package com.xuexue.firstproject;
    
    import com.xuexue.firstproject.Quartz.MyJobFactory;
    import lixue.ILiXue;
    import org.quartz.Scheduler;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.quartz.SchedulerFactoryBean;
    
    @SpringBootApplication
    public class FirstprojectApplication {
    
        @Autowired
        private MyJobFactory myJobFactory;
    
        public static void main(String[] args) {
            SpringApplication.run(FirstprojectApplication.class, args);
    
        }
    
        @Bean
        public SchedulerFactoryBean schedulerFactoryBean() {
            SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
            // 延时启动
            schedulerFactoryBean.setStartupDelay(20);
            // 自定义Job Factory,用于Spring注入
            schedulerFactoryBean.setJobFactory(myJobFactory);
            System.out.println("myJobFactory:"+myJobFactory);
            return schedulerFactoryBean;
        }
    
        @Bean
        public Scheduler scheduler() {
            return schedulerFactoryBean().getScheduler();
        }
    
    }
    

    2.3.6删除ApplicationStartQuartzJobListener类中注入Scheduler 的代码

        /**
         * 初始注入scheduler
         */
        @Bean
        public Scheduler scheduler() throws SchedulerException{
            SchedulerFactory schedulerFactoryBean = new StdSchedulerFactory();
            return schedulerFactoryBean.getScheduler();
        }

    2.3.7编译,启动,这次就成功的注入进去了,控制台输出结果

        至此操作数据库的部分就结束了。Quartz定时任务的框架的优势就在于能够动态的管理我们的任务,那么接下来就写一个API管理我们的任务了

    2.4Quartz的API

        这个API只是一个简单的例子,在操作上的还是会有一些漏洞。仅供参考,主要是体验一下如何动态的操作任务的,更加丰富完善的功能,还有待大家丰富。如有错误,请大家批评指正。

    2.4.1设计数据库,储存任务列表,创建对应的实体类

    package com.xuexue.firstproject.Beans;
    
    import com.baomidou.mybatisplus.activerecord.Model;
    import com.baomidou.mybatisplus.annotations.TableId;
    import com.baomidou.mybatisplus.annotations.TableName;
    import com.baomidou.mybatisplus.enums.IdType;
    
    import java.io.Serializable;
    import java.util.Date;
    @TableName("lx_job_info")
    public class LxJobInfo extends Model<LxJobInfo> {
        /**
         * 任务id
         */
        @TableId(value = "job_id",type=IdType.AUTO)
        private Integer jobId;
        /**
         * 任务的jobkey 唯一地识别一个Job
         */
        private String jobName;
        /**
         * 任务的TriggerKey来唯一地识别一个Trigger
         */
        private String jobGroup;
        /**
         * 任务的所在类的全路径
         */
        private String jobClass;
        /**
         * 任务执行的cron表达式
         */
        private String jobCron;
        /**
         * 任务状态 0停止状态,1启动状态,2暂停状态
         */
            private Integer jobState;
        /**
         * 任务创建时间
         */
        private Date jobCreatetime;
        /**
         * 任务修改时间
         */
        private Date jobUpdatetime;
    
        public Integer getJobId() {
            return jobId;
        }
    
        public void setJobId(Integer jobId) {
            this.jobId = jobId;
        }
    
        public String getJobName() {
            return jobName;
        }
    
        public void setJobName(String jobName) {
            this.jobName = jobName;
        }
    
        public String getJobGroup() {
            return jobGroup;
        }
    
        public void setJobGroup(String jobGroup) {
            this.jobGroup = jobGroup;
        }
    
        public String getJobClass() {
            return jobClass;
        }
    
        public void setJobClass(String jobClass) {
            this.jobClass = jobClass;
        }
    
        public String getJobCron() {
            return jobCron;
        }
    
        public void setJobCron(String jobCron) {
            this.jobCron = jobCron;
        }
    
        public Integer getJobState() {
            return jobState;
        }
    
        public void setJobState(Integer jobState) {
            this.jobState = jobState;
        }
    
        public Date getJobCreatetime() {
            return jobCreatetime;
        }
    
        public void setJobCreatetime(Date jobCreatetime) {
            this.jobCreatetime = jobCreatetime;
        }
    
        public Date getJobUpdatetime() {
            return jobUpdatetime;
        }
    
        public void setJobUpdatetime(Date jobUpdatetime) {
            this.jobUpdatetime = jobUpdatetime;
        }
    
        @Override
        protected Serializable pkVal() {
            return null;
        }
    }

    2.4.2对应的service

    package com.xuexue.firstproject.Services;
    
    import com.baomidou.mybatisplus.service.IService;
    import com.xuexue.firstproject.Beans.LxJobInfo;
    
    import java.util.List;
    
    public interface ILxJobInfoService extends IService<LxJobInfo> {
        //获取job的列表
        List<LxJobInfo> getJobList();
        //改变任务状态
        void updateJobState(LxJobInfo lxJobInfo);
    }
    
    package com.xuexue.firstproject.Services.imp;
    
    import com.baomidou.mybatisplus.mapper.EntityWrapper;
    import com.baomidou.mybatisplus.service.impl.ServiceImpl;
    import com.xuexue.firstproject.Beans.LxJobInfo;
    import com.xuexue.firstproject.Daos.LxJobInfoMapper;
    import com.xuexue.firstproject.Services.ILxJobInfoService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    @Service
    public class LxJobInfoService  extends ServiceImpl<LxJobInfoMapper,LxJobInfo> implements ILxJobInfoService{
        @Autowired
        LxJobInfoMapper lxJobInfoMapper;
        /**
         *查询任务列表
         */
        @Override
        public List<LxJobInfo> getJobList() {
            return lxJobInfoMapper.getJobList();
            //return lxJobInfoMapper.selectList(new EntityWrapper<>());
        }
        
        /**
         *修改任务状态
         */
        @Override
        public void updateJobState(LxJobInfo lxJobInfo) {
            lxJobInfoMapper.updateById(lxJobInfo);
        }
    
    }

    2.4.3对应的mapper

    package com.xuexue.firstproject.Daos;
    
    import com.baomidou.mybatisplus.mapper.BaseMapper;
    import com.xuexue.firstproject.Beans.LxJobInfo;
    import org.apache.ibatis.annotations.Mapper;
    
    import java.util.List;
    @Mapper
    public interface LxJobInfoMapper extends BaseMapper<LxJobInfo> {
        //获取job的列表
        List<LxJobInfo> getJobList();
    }
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
    	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.xuexue.firstproject.Daos.LxJobInfoMapper">
    	
    	<resultMap id="LxJobInfo" type="com.xuexue.firstproject.Beans.LxJobInfo" >
    		<result column="job_id" property="jobId" />
    	    <result column="job_name" property="jobName" />
    	    <result column="job_group" property="jobGroup" />
    	    <result column="job_class" property="jobClass" />
    		<result column="job_cron" property="jobCron" />
    		<result column="job_state" property="jobState" />
    		<result column="job_createtime" property="jobCreatetime" />
    		<result column="job_updatetime" property="jobUpdatetime" />
    	</resultMap>
    
    	<sql id="Base_Column_List">
    		t.job_id,
    		t.job_name,
    		t.job_group,
    		t.job_class,
    		t.job_cron,
    		t.job_state,
    		t.job_createtime,
    		t.job_updatetime
    	</sql>
    
    	<select id="getJobList" resultMap="LxJobInfo">
    		select t.job_id,
    		t.job_name,
    		t.job_group,
    		t.job_class,
    		t.job_cron,
    		t.job_state,
    		t.job_createtime,
    		t.job_updatetime
    		from lx_job_info t
    	</select>
    
    </mapper>

    2.4.4对应的controller

    package com.xuexue.firstproject.Controllers;
    
    
    import com.baomidou.mybatisplus.mapper.EntityWrapper;
    import com.xuexue.firstproject.Beans.LxJobInfo;
    import com.xuexue.firstproject.Quartz.QuartzJobScheduler;
    import com.xuexue.firstproject.Services.imp.LxJobInfoService;
    import org.quartz.SchedulerException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.List;
    
    @Controller
    @RequestMapping("/quartz")
    public class QuartzApiController {
    
        @Autowired
        private QuartzJobScheduler quartzJobScheduler;
    
        @Autowired
        private LxJobInfoService lxJobInfoService;
    
        /**
         * @Author: lixue
         * @Description: 访问quartz.html页面
         * @Date: 2019/11/6 13:51
         * @param
         */
        @RequestMapping(value = "/toQuartz", method = RequestMethod.GET)
        public String toQuartz(){
            return "quartz/quartz.html";
        }
    
        /**
         * @Author: lixue
         * @Description: 查询任务列表
         * @Date: 2019/11/5 9:45
         * @param
         */
        @RequestMapping(value = "/getJobList", method = RequestMethod.POST)
        @ResponseBody
        public List<LxJobInfo> getJobList(){
            return lxJobInfoService.getJobList();
        }
    
        /**
         * @Author: lixue
         * @Description: 开启全部任务
         * @Date: 2019/11/6 14:02
         * @param
         */
        @RequestMapping(value = "/startAll", method = RequestMethod.POST)
        @ResponseBody
        public String startAll(){
    
            try {
            //获取任务列表
            List<LxJobInfo> list=lxJobInfoService.getJobList();
            //调用开启所有任务的方法
            quartzJobScheduler.startAllJob(list);
            //改变数据库中任务的状态为开启状态
             for(int i=0;i<list.size();i++){
                 list.get(i).setJobState(1);
                 lxJobInfoService.updateById(list.get(i));
             }
    
            //返回成功的字符串
            return "{\"result\":true}";
    
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
    
        }
    
        /**
         * @Author: lixue
         * @Description: 暂停全部任务
         * @Date: 2019/11/6 17:15
         * @param
         */
        @RequestMapping(value = "/suspendAll", method = RequestMethod.POST)
        @ResponseBody
        public String suspendAll(){
    
            try {
                //调用暂停所有任务的方法
                quartzJobScheduler.pauseAllJob();
                //改变数据库中任务的状态为暂停状态
                List<LxJobInfo> list=lxJobInfoService.getJobList();
                for(int i=0;i<list.size();i++){
                    list.get(i).setJobState(2);
                    lxJobInfoService.updateById(list.get(i));
                    //lxJobInfoService.updateJobState(list.get(i));
                }
                //返回成功的字符串
                return "{\"result\":true}";
    
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
        /**
         * @Author: lixue
         * @Description: 开启一个任务
         * @Date: 2019/11/6 17:14
         * @param jobId
         */
        @RequestMapping(value = "/startOne", method = RequestMethod.POST)
        @ResponseBody
        public String startOne(Integer jobId){
    
            try {
    
                LxJobInfo lxJobInfo=lxJobInfoService.selectById(jobId);
                //调用开启所有任务的方法
    
                quartzJobScheduler.startOneJob(lxJobInfo);
                //改变数据库中任务的状态为开启状态
                lxJobInfo.setJobState(1);
                lxJobInfoService.updateById(lxJobInfo);
    
                //返回成功的字符串
                return "{\"result\":true}";
    
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
        /**
         * @Author: lixue
         * @Description: 暂停一个任务
         * @Date: 2019/11/6 17:14
         * @param jobId
         */
        @RequestMapping(value = "/suspendOne", method = RequestMethod.POST)
        @ResponseBody
        public String suspendOne(Integer jobId){
    
            try {
    
                LxJobInfo lxJobInfo=lxJobInfoService.selectById(jobId);
                //调用开启所有任务的方法
                quartzJobScheduler.pauseJob(lxJobInfo.getJobName(),lxJobInfo.getJobGroup());
                //改变数据库中任务的状态为暂停状态
                lxJobInfo.setJobState(2);
                lxJobInfoService.updateById(lxJobInfo);
    
                //返回成功的字符串
                return "{\"result\":true}";
    
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        /**
         * @Author: lixue
         * @Description: 恢复一个任务
         * @Date: 2019/11/7 8:56
         * @param jobId
         */
        @RequestMapping(value = "/resumeOne", method = RequestMethod.POST)
        @ResponseBody
        public String resumeOne(Integer jobId){
    
            try {
                LxJobInfo lxJobInfo=lxJobInfoService.selectById(jobId);
                //调用开启所有任务的方法
                quartzJobScheduler.resumeJob(lxJobInfo.getJobName(),lxJobInfo.getJobGroup());
                //改变数据库中任务的状态为启动状态
                lxJobInfo.setJobState(1);
                lxJobInfoService.updateById(lxJobInfo);
    
                //返回成功的字符串
                return "{\"result\":true}";
    
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        @RequestMapping(value = "/addOneJob", method = RequestMethod.POST)
        @ResponseBody
        public String addOneJob(LxJobInfo lxJobInfo){
            lxJobInfoService.insert(lxJobInfo);
            return "{\"result\":true}";
        }
    
    
    }
    

    2.4.5对应的页面和js

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
        <div id="tablediv">
            <button id="startAll">开启全部任务</button>
            <button id="suspendAll">暂停全部任务</button>
            <table id="quartzTable"></table>
        </div>
        <from id="addJobFrom">
            name:<input type="text" id="jobName" name="jobName">
            group:<input type="text" id="jobGroup" name="jobName">
            类全路径:<input type="text" id="jobClass" name="jobName">
            cron:<input type="text" id="jobCron" name="jobName">
            <button id="addOneJob">添加任务</button>
        </from>
        <script type="text/javascript" src="../static/jquery.min.js"></script>
        <script type="text/javascript" src="../static/quartz/quartz.js"></script>
    </body>
    
    </html>
    $(function(){
        getJobList();
    
        /**
         * 点击开启全部
         */
        $("#startAll").click(function(){
            //发送ajax请求
            $.ajax({
                url:"startAll",
                type:"post",
                dataType:"json",
                success:function(data){
                    if (data){
                        alert("开启成功");
                    }else{
                        alert("开启失败");
                    }
                    //刷新表格
                    //$(".state").html("启动状态");
                    getJobList();
                },
                error:function(err){
                    console.log(err);
                }
            })
    
        });
    
        /**
         * 点击暂停全部
         */
        $("#suspendAll").click(function(){
            //发送ajax请求
            $.ajax({
                url:"suspendAll",
                type:"post",
                dataType:"json",
                success:function(data){
                    if (data){
                        alert("暂停成功");
                    }else{
                        alert("暂停失败");
                    }
                    //刷新表格
                    //$(".state").html("暂停状态");
                    getJobList();
                },
                error:function(err){
                    console.log(err);
                }
            });
    
        });
    
        /**
         * 点击添加任务
         */
    
    
    })
    /**
     * 展示任务列表
     */
    function getJobList(){
        $("#quartzTable").html("");
        $.ajax({
            url:"getJobList",
            type:"post",
            dataType:"json",
            success:function(data){
                //console.log(data);
                var str='<tr><th>序号</th><th>name</th><th>group</th><th>类全路径</th><th>cron</th><th>状态</th><th>操作</th></tr>';
    
                for (var i=0;i<data.length;i++){
                    str+='<tr>';
                    str+='<td>'+data[i].jobId+'</td>';
                    str+='<td>'+data[i].jobName+'</td>';
                    str+='<td>'+data[i].jobGroup+'</td>';
                    str+='<td>'+data[i].jobClass+'</td>';
                    str+='<td>'+data[i].jobCron+'</td>';
    
                    var state="";
                    if(data[i].jobState==0){
                        state="停止状态";
                    }
                    if(data[i].jobState==1){
                        state="启动状态";
                    }
                    if(data[i].jobState==2){
                        state="暂停状态";
                    }
    
                    str+='<td><button class="state">'+state+'</button></td>';
                    str+='<td><button onclick="startOneJob('+data[i].jobId+')">开启</button>' +
                        '<button onclick="resumeOneJob('+data[i].jobId+')">恢复</button>' +
                        '<button onclick="suspendOneJob('+data[i].jobId+')">暂停</button>' +
                        '<button onclick="stopOneJob('+data[i].jobId+')">停止</button></td>';
                    str+='</tr>';
                }
                $("#quartzTable").html(str);
            },
            error:function(err){
                console.log(err);
            }
        });
    }
    
    /**
     * 开启一个任务
     */
    function startOneJob(jobId){
        $.ajax({
            url:"startOne",
            type:"post",
            data:{jobId:jobId},
            dataType:"json",
            success:function(data){
                if (data){
                    alert("启动成功");
                }else{
                    alert("启动失败");
                }
                //刷新表格
                //$(".state").html("暂停状态");
                getJobList();
            },
            error:function(err){
                console.log(err);
            }
        });
    }
    
    /**
     * 暂停一个任务
     */
    function suspendOneJob(jobId){
        $.ajax({
            url:"suspendOne",
            type:"post",
            data:{jobId:jobId},
            dataType:"json",
            success:function(data){
                if (data){
                    alert("暂停成功");
                }else{
                    alert("暂停失败");
                }
                //刷新表格
                //$(".state").html("暂停状态");
                getJobList();
            },
            error:function(err){
                console.log(err);
            }
        });
    }
    
    /**
     * 恢复一个任务
     */
    function resumeOneJob(jobId){
        $.ajax({
            url:"resumeOne",
            type:"post",
            data:{jobId:jobId},
            dataType:"json",
            success:function(data){
                if (data){
                    alert("恢复成功");
                }else{
                    alert("恢复失败");
                }
                //刷新表格
                //$(".state").html("暂停状态");
                getJobList();
            },
            error:function(err){
                console.log(err);
            }
        });
    }

    2.4.6修改一下我们前面的QuartzJobScheduler类

    package com.xuexue.firstproject.Quartz;
    
    import com.xuexue.firstproject.Beans.LxJobInfo;
    import org.quartz.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.Date;
    import java.util.List;
    
    @Configuration
    public class QuartzJobScheduler {
        // 任务调度
        @Autowired
        private Scheduler scheduler;
    
    
        /**
         * 开始执行所有任务
         */
        public void startJob() throws SchedulerException {
            //startJob1(scheduler);
            //startOneJob(scheduler,"job2","group2","0 0/1 * * * ?",QuartzJob2.class);
            //startJob2(scheduler);
            startJob3(scheduler);
            scheduler.start();
        }
        /**
         * 修改某个任务的执行时间
         *
         * @param name
         * @param group
         * @param time
         * @return
         * @throws SchedulerException
         */
        public boolean modifyJob(String name, String group, String time) throws SchedulerException {
            Date date = null;
            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;
        }
    
        /**
         * @Author: lixue
         * @Description: 获取job信息
         * @Date: 2019/11/4 14:38
         * @param name
         * @param group
         */
        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());
        }
    
        /**
         * @Author: lixue
         * @Description: 暂停所有任务
         * @Date: 2019/11/4 14:18
         * @param
         */
        public void pauseAllJob() throws SchedulerException {
            scheduler.pauseAll();
        }
    
    
        /**
         * @Author: lixue
         * @Description: 暂停一个任务
         * @Date: 2019/11/4 14:17
         * @param name
         * @param group
         */
        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);
        }
    
        /**
         * @Author: lixue
         * @Description: 删除一个任务(从任务列表中删除)
         * @Date: 2019/10/30 17:29
         * @param name
         * @param group
         */
        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);
        }
    
        /**
         * @Author: lixue
         * @Description: 开启全部job(添加进任务列表,并启动)
         * @Date: 2019/10/28 10:38
         * @param lxJobInfoList job的list集合
         */
        public void startAllJob(List<LxJobInfo> lxJobInfoList)throws SchedulerException,ClassNotFoundException{
    
            for(int i=0;i<lxJobInfoList.size();i++){
                //反射机制
                Class jobClass = Class.forName(lxJobInfoList.get(i).getJobClass());
                // 通过JobBuilder构建JobDetail实例,JobDetail规定只能是实现Job接口的实例
                // JobDetail 是具体Job实例
                JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(lxJobInfoList.get(i).getJobName(), lxJobInfoList.get(i).getJobGroup()).build();
                // 基于表达式构建触发器
                CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(lxJobInfoList.get(i).getJobCron());
                // CronTrigger表达式触发器 继承于Trigger
                // TriggerBuilder 用于构建触发器实例
                CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(lxJobInfoList.get(i).getJobName(), lxJobInfoList.get(i).getJobGroup())
                        .withSchedule(cronScheduleBuilder).build();
                //让调度器 使触发器和任务关联
                scheduler.scheduleJob(jobDetail, cronTrigger);
            }
            //启动任务调度器
            scheduler.start();
        }
        /**
         * @Author: lixue
         * @Description: 开启一个job(添加进任务列表,并启动)
         * @Date: 2019/10/28 15:44
         * @param lxJobInfo 一个job对象
         */
        public void startOneJob(LxJobInfo lxJobInfo) throws SchedulerException ,ClassNotFoundException{
    
            Class jobClass = Class.forName(lxJobInfo.getJobClass());
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(lxJobInfo.getJobName(), lxJobInfo.getJobGroup()).build();
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(lxJobInfo.getJobCron());
            CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(lxJobInfo.getJobName(), lxJobInfo.getJobGroup())
                    .withSchedule(cronScheduleBuilder).build();
            //让调度器 使触发器和任务关联
            scheduler.scheduleJob(jobDetail, cronTrigger);
            //启动任务调度器
            scheduler.start();
        }
    
        /*
        /**
         * @Author: lixue
         * @Description: 开启一个job  暂时不适用
         * @Date: 2019/10/26 14:15
         * @param scheduler 任务调度
         * @param name  jobkey 唯一地识别一个Job
         * @param group TriggerKey来唯一地识别一个Trigger
         * @param cron corn表达式
         * @param classs 任务的类
         */
        /*public void startOneJob(Scheduler scheduler, String name, String group, String cron, Class  classs) throws SchedulerException {
            //Class.forName("com.");
            JobDetail jobDetail = JobBuilder.newJob(classs).withIdentity(name, group).build();
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
            CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(name, group)
                    .withSchedule(cronScheduleBuilder).build();
            //让调度器 使触发器和任务关联
            scheduler.scheduleJob(jobDetail, cronTrigger);
            //启动任务调度器
            //scheduler.start();
        }*/
        private void startJob1(Scheduler scheduler) throws SchedulerException {
            // 通过JobBuilder构建JobDetail实例,JobDetail规定只能是实现Job接口的实例
            // JobDetail 是具体Job实例
            JobDetail jobDetail = JobBuilder.newJob(QuartzJob1.class).withIdentity("job1", "group1").build();
            // 基于表达式构建触发器
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
            // CronTrigger表达式触发器 继承于Trigger
            // TriggerBuilder 用于构建触发器实例
            CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job1", "group1")
                    .withSchedule(cronScheduleBuilder).build();
            scheduler.scheduleJob(jobDetail, cronTrigger);
        }
    
        private void startJob2(Scheduler scheduler) throws SchedulerException {
            JobDetail jobDetail = JobBuilder.newJob(QuartzJob2.class).withIdentity("job2", "group2").build();
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 0/1 * * * ?");
            CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job2", "group2")
                    .withSchedule(cronScheduleBuilder).build();
            scheduler.scheduleJob(jobDetail, cronTrigger);
        }
        private void startJob3(Scheduler scheduler) throws SchedulerException {
            JobDetail jobDetail = JobBuilder.newJob(QuartzJob3.class).withIdentity("job3", "group3").build();
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
            CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job3", "group3")
                    .withSchedule(cronScheduleBuilder).build();
            scheduler.scheduleJob(jobDetail, cronTrigger);
        }
    }
    

    2.4.7因为采用的是自动控制的,所以我们要将ApplicationStartQuartzJobListener类里面的内容注释掉,并让这个类不再实现ApplicationListener<ContextRefreshedEvent>

    2.4.8编译,运行后出现如下页面

    点击开启会开启一个任务,点击开启全部会开启全部任务,点击暂停会暂停任务,点击恢复会回复任务。

    2.4.9项目中的瑕疵

    这个小练习只是体验一下quartz框架的使用,在写的程序会有比较多的逻辑漏洞,还请大家谅解,更严谨完善的功能还需要大家自己根据实际情况进行完善以及修改。

    1、开启全部任务没有筛选出已经开启的任务

    2、关闭程序后再开启,状态显示的与实际情况不符

    3、添加功能是没有实现的

    三、感谢

    在学习过程中,参考了很多的文章,如下几篇文章对我的帮助很大。

    https://blog.csdn.net/u013042707/article/details/82934725

    https://blog.csdn.net/upxiaofeng/article/details/79415108

    https://blog.csdn.net/fly_captain/article/details/84257781

    展开全文
  • Quartz定时框架CronTrigger开发使用public class HelloJob implements Job { public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("Hello,Quartz!"); } }p
  • Quartz定时框架入门

    2019-09-23 08:09:19
    Quartz框架是Java开源的定时任务调度器,Quartz框架中有如下核心概念: 1. Job  任务接口,接口中只声明方法void execute(JobExecutionContext context),接口的声明如下: public interface Job { void ...
  • quartz定时框架学习

    2021-01-24 23:08:25
    quartz工具类 package com.syx.task; import org.quartz.*; import org.quartz.impl.JobDetailImpl; import org.quartz.impl.StdSchedulerFactory; import org.quartz.impl.triggers.CronTriggerImpl; import java...
  • Quartz定时框架总结

    2019-12-10 22:18:48
    文章目录一、quartz介绍二、核心概念1、trigger2、job3、scheduler4、作业管理和存储三、核心类和关系1.核心类2.关系:四、quartz使用1.依赖2.原生应用3.Quartz+Spring集成使用 一、quartz介绍 Quartz是OpenSymphony...
  • Quartz:是一个开放源代码任务调度框架Quartz功能强大,可以让你的程序在指定时间执行,也可以按照某一个频度执行,支持数据库、监听器、插件、集群等特性。 使用场景:定时消息推送、定时抢购、定时发送邮件、...
  • Quartz定时框架的使用、与spring整合的使用 ** 一、Quartz是什么 Quartz是一个日常任务管理系统,也可以说成是一个定时器,他可以和任何其他软件系统集成或者一起使用。Quartz 相当“轻量”,并且需要非常少的...
  • 定时任务创建方法与特点 springboot定时任务主要有以下三种创建方式: 1、基于注解(@Scheduled) 基于注解@Scheduled默认为单线程,开启多个任务时,任务的执行时机会受上一个任务执行时间的影响。 @Configuration ...
  • java使用quartz定时框架

    千次阅读 2019-06-20 17:49:08
    1,下载jar包 2,新建两个任务 PrintJobEvery3Seconds.java和PrintJobOnMonday10.java package com.practice.quartz;...import org.quartz.Job;...import org.quartz....import org.quartz.JobExecutionExc...
  • 第一步:导入依赖 <dependency>...spring-boot-starter-quartz</artifactId> </dependency> 第二步:定时任务接口 public interface WeatherDataService { /** * 根据城市Id来同步天气

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,665
精华内容 1,466
关键字:

quartz定时框架