Quarzt的学习以及系统配置自启动

一:Quartz的介绍

Quartz:是机遇java实现的任务调度框架,用于执行想要执行的任何任务

Quartz设计模式:
Builder模式
Factory模式
组件模式
链式编程

任务Job
job:就是你想要实现的任务类,每一个job必须实现org.quartz.job,且只需实现接口定义的
execute()方法

触发器Trigger
Trigger为你执行任务的触发器,比如你想每天3点发送一份统计邮件,Trigger将
会设置3点进行执行该任务。Trigger包含两种SimpleTrigger和CronTrigger两种

调度器Scheduler
Scheduler为任务的调度器,它会将任务job及触发器Trigger整合起来,
负责基于Trigger设定的时间来执行job.

Quartz的几个常用API
以下是Quartz编程API重要接口,也是Quartz的重要组件

shceduler:用于与调度程序交互的主程序接口
Scheduler调度程序-任务执行计划表,只有安排进执行计划的任务job
(通过Scheduler.shcerdulejob方法安排进执行计划),当它预先定义的执行
时间到了的时候(任务触发Trigger),该任务才会执行

job:我们预先定义的希望在未来时间能被调度程序执行的任务类,可以自定义

jobDetail:使用jobDeatail来定义定时任务的实例,JobDetail实例是
通过JobBuildder类创建的

JobDataMap:可以包含不限量的(序列化的)数据对象,在job实例执行的时候
,可以使用其中的数据;jobDataMap是java Map接口的一个实现,额外增加
了一些便于存取基本类型的数据的方法

Trigger触发器:Trigger对象是用来出发执行job的。当调度一个job时,我们实例
一个触发器然后调整它的属性来满足job执行的条件。表明任务在什么时候会执行。
定义了一个已经被安排的任务将会在什么时候执行的时间条件,比如每2秒就执行一次

JobBuilder:用于声明一个任务实例,也可以定义关于该任务的详情比如任务名、
组名等,这个1声明的实例将会作为一个实际执行的任务

TriggerBuilder:触发器创建器,用于创建触发器trigger实例

JobListener、TriggerListener、SchedulerListener:监听器,用于对组件的监听

JobDataMap介绍:
(1)使用Map获取。

  • 在进行任务调度时,JobDataMap存储在JobExecutionContext中 ,非常方便获取。
  • JobDataMap可以用来装载任何可序列化的数据对象,当job实例对象被执行时这些参数对象会传递给它。
  • JobDataMap实现了JDK的Map接口,并且添加了非常方便的方法用来存取基本数据类型。

有状态的Job和无状态的Job:
@PersistJobDataAfterExecution//多次调用job时候,会对job进行持久化
没加这个注解会每次创建一个新的jobDataMap。

有状态的Job可以理解为多次Job调用期间可以持有一些状态信息,这些状态信息存储在JobDataMap中,
而默认的无状态job每次调用时都会创建一个新的JobDataMap。

Trigger介绍
Quartz有一些不同的触发器类型,不过,用得最多的是SimpleTrigger和CronTrigger。

(1)jobKey
表示job实例的标识,触发器被触发时,该指定的job实例会被执行。

(2)startTime
表示触发器的时间表,第一次开始被触发的时间,它的数据类型是java.util.Date。

(3)endTime
指定触发器终止被触发的时间,它的数据类型是java.util.Date。

JobExecutionContext介绍

  • 当Scheduler调用一个Job,就会将JobExecutionContext传递给Job的execute()方法;
  • Job能通过JobExecutionContext对象访问到Quartz运行时候的环境以及Job本身的明细数据。

SimpleTrigger触发器

SimpleTrigger对于设置和使用是最为简单的一种 QuartzTrigger。

它是为那种需要在特定的日期/时间启动,且以一个可能的间隔时间重复执行 n 次的 Job 所设计的。

  • SimpleTrigger的属性有:开始时间、结束时间、重复次数和重复的时间间隔。
  • 重复次数属性的值可以为0、正整数、或常量 SimpleTrigger.REPEAT_INDEFINITELY。
  • 重复的时间间隔属性值必须为大于0或长整型的正整数,以毫秒作为时间单位,当重复的时间间隔为0时,意味着与Trigger同时触发执行。
  • 如果有指定结束时间属性值,则结束时间属性优先于重复次数属性,这样的好处在于:当我们需要创建一个每间隔10秒钟触发一次直到指定的结束时间的 Trigger,而无需去计算从开始到结束的所重复的次数,我们只需简单的指定结束时间和使用REPEAT_INDEFINITELY作为重复次数的属性 值即可。

CronTrigger触发器

如果你需要像日历那样按日程来触发任务,而不是像SimpleTrigger 那样每隔特定的间隔时间触发,CronTriggers通常比SimpleTrigger更有用,因为它是基于日历的作业调度器。

使用CronTrigger,你可以指定诸如“每个周五中午”,或者“每个工作日的9:30”或者“从每个周一、周三、周五的上午9:00到上午10:00之间每隔五分钟”这样日程安排来触发。甚至,象SimpleTrigger一样,CronTrigger也有一个startTime以指定日程从什么时候开始,也有一个(可选的)endTime以指定何时日程不再继续。

(1)Cron Expressions——Cron 表达式

Cron表达式被用来配置CronTrigger实例。Cron表达式是一个由7个子表达式组成的字符串。每个子表达式都描述了一个单独的日程细节。这些子表达式用空格分隔,分别表示:

  1. Seconds 秒
  2. Minutes 分钟
  3. Hours 小时
  4. Day-of-Month 月中的天
  5. Month 月
  6. Day-of-Week 周中的天
  7. Year (optional field) 年(可选的域)

单个子表达式可以包含范围或者列表。例如:前面例子中的周中的天这个域(这里是"WED")可以被替换为"MON-FRI",
“MON, WED, FRI"或者甚至"MON-WED,SAT”。

所有的域中的值都有特定的合法范围,这些值的合法范围相当明显,例如:秒和分域的合法值为0到59,
小时的合法范围是0到23,Day-of-Month中值得合法凡范围是1到31,但是需要注意不同的月份中的天数不同。
月份的合法值是1到12。或者用字符串JAN,FEB MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV 及DEC来表示。
Days-of-Week可以用1到7来表示(1=星期日)或者用字符串SUN, MON, TUE, WED, THU, FRI 和SAT来表示.

“0 0 10,14,16 * * ?” 每天上午10点,下午2点,4点
“0 0/30 9-17 * * ?” 朝九晚五工作时间内每半小时,从0分开始每隔30分钟发送一次
“0 0 12 ? * WED” 表示每个星期三中午12点
“0 0 12 * * ?” 每天中午12点触发
“0 15 10 ? * *” 每天上午10:15触发
“0 15 10 * * ?” 每天上午10:15触发
“0 15 10 * * ? *” 每天上午10:15触发
“0 15 10 * * ? 2005” 2005年的每天上午10:15触发
“0 * 14 * * ?” 在每天下午2点到下午2:59期间的每1分钟触发
“0 0/55 14 * * ?” 在每天下午2点到下午2:55期间,从0开始到55分钟触发
“0 0/55 14,18 * * ?” 在每天下午2点到2:55期间和下午6点到6:55期间的,从0开始到55分钟触发
“0 0-5 14 * * ?” 在每天下午2点到下午2:05期间的每1分钟触发
“0 10,44 14 ? 3 WED” 每年三月的星期三的下午2:10和2:44触发
“0 15 10 ? * MON-FRI” 周一至周五的上午10:15触发
“0 15 10 15 * ?” 每月15日上午10:15触发
“0 15 10 L * ?” 每月最后一日的上午10:15触发
“0 15 10 ? * 6L” 每月的最后一个星期五上午10:15触发
“0 15 10 ? * 6L 2002-2005” 2002年至2005年的每月的最后一个星期五上午10:15触发
“0 15 10 ? * 6#3” 每月的第三个星期五上午10:15触发

Quartz监听器
Quartz的监听器用于当任务调度中你所关注事件发生时,能够及时获取这一事件的通知。类似于任务执行过程中的邮件、短信类的提醒。Quartz监听器主要有JobListener、TriggerListener、SchedulerListener三种,顾名思义,分别表示任务、触发器、调度器对应的监听器。
三者的使用方法类似,在开始介绍三种监听器之前,需要明确两个概念:全局监听器与非全局监听器,二者的区别在于:

全局监听器能够接收到所有的Job/Trigger的事件通知,

而非全局监听器只能接收到在其上注册的Job或Trigger的事件,不在其上注册的Job或Trigger则不会进行监听。

二:Quartz的使用

<dependencies>
    		<dependency>
    			<groupId>org.quartz-scheduler</groupId>
    			<artifactId>quartz</artifactId>
    			<version>2.3.0</version>
    		</dependency>
            <dependency>
    			<groupId>junit</groupId>
    			<artifactId>junit</artifactId>
    			<version>4.12</version>
    		</dependency>
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>slf4j-log4j12</artifactId>
    			<version>1.7.5</version>
    		</dependency>
    		<dependency>
    			<groupId>log4j</groupId>
    			<artifactId>log4j</artifactId>
    			<version>1.2.15</version>
    		</dependency>
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<version>3.5.1</version>
    				<configuration>
    					<target>1.8</target>
    					<source>1.8</source>
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>
HelloJobCronTrigger.java

	// 定义任务类
	public class HelloJobCronTrigger implements Job {


		@Override
		public void execute(JobExecutionContext context) throws JobExecutionException {
			// 定义时间
			Date date = new Date();
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String dateString = dateFormat.format(date);
			
			// 定义工作任务内容
			System.out.println("进行数据库备份操作。当前任务执行的时间:"+dateString);
		}
	}


HelloSchedulerDemoCronTrigger.java

	public class HelloSchedulerDemoCronTrigger {

		public static void main(String[] args) throws Exception {
			// 1:从工厂中获取任务调度的实例
	        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
	
	        // 2:定义一个任务调度实例,将该实例与HelloJob绑定,任务类需要实现Job接口
	        JobDetail job = JobBuilder.newJob(HelloJobCronTrigger.class)
	        		.withIdentity("job1", "group1") // 定义该实例唯一标识
	        		.build();
	
	        // 3:定义触发器 ,马上执行, 然后每5秒重复执行一次
	        Trigger trigger = TriggerBuilder.newTrigger()
	        		.withIdentity("trigger1", "group1") // 定义该实例唯一标识
	        		.withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * 6 4 ?"))// 定义表达式
	        		.build();
	
	        // 4:使用触发器调度任务的执行
	        scheduler.scheduleJob(job, trigger);
	        
	        // 5:开启
	        scheduler.start();
	        // 关闭
	        // scheduler.shutdown();
		}
	}

三:任务监听器方法

JobListener
    public interface JobListener {

      	String getName();
      	
      	void jobToBeExecuted(JobExecutionContext context);
      	
      	void jobExecutionVetoed(JobExecutionContext context);

        void jobWasExecuted(JobExecutionContext context,
                JobExecutionException jobException);
    }

其中:

  1. getName方法:用于获取该JobListener的名称。

  2. jobToBeExecuted方法:Scheduler在JobDetail将要被执行时调用这个方法。

  3. jobExecutionVetoed方法:Scheduler在JobDetail即将被执行,但又被TriggerListerner否决时会调用该方法

  4. jobWasExecuted方法:Scheduler在JobDetail被执行之后调用这个方法

四:触发器监听器方法

TriggerListener
public interface TriggerListener {

    public String getName();

    public void triggerFired(Trigger trigger, JobExecutionContext context);

    public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context);

    public void triggerMisfired(Trigger trigger);

    public void triggerComplete(Trigger trigger, JobExecutionContext context,
            int triggerInstructionCode);
}

其中:

  1. getName方法:用于获取触发器的名称

  2. triggerFired方法:当与监听器相关联的Trigger被触发,Job上的execute()方法将被执行时,Scheduler就调用该方法。

  3. vetoJobExecution方法:在 Trigger 触发后,Job 将要被执行时由 Scheduler 调用这个方法。TriggerListener 给了一个选择去否决 Job 的执行。假如这个方法返回 true,这个 Job 将不会为此次 Trigger 触发而得到执行。

  4. triggerMisfired方法:Scheduler 调用这个方法是在 Trigger 错过触发时。你应该关注此方法中持续时间长的逻辑:在出现许多错过触发的 Trigger 时,长逻辑会导致骨牌效应。你应当保持这上方法尽量的小。

  5. triggerComplete方法:Trigger 被触发并且完成了 Job 的执行时,Scheduler 调用这个方法。

五:调度器监听器方法

SchedulerListener

public interface SchedulerListener {

    public void jobScheduled(Trigger trigger);

    public void jobUnscheduled(String triggerName, String triggerGroup);

    public void triggerFinalized(Trigger trigger);

    public void triggersPaused(String triggerName, String triggerGroup);

    public void triggersResumed(String triggerName, String triggerGroup);

    public void jobsPaused(String jobName, String jobGroup);

    public void jobsResumed(String jobName, String jobGroup);

    public void schedulerError(String msg, SchedulerException cause);

    public void schedulerStarted();

    public void schedulerInStandbyMode();

    public void schedulerShutdown();

    public void schedulingDataCleared();
}

其中:

  1. jobScheduled方法:用于部署JobDetail时调用

  2. jobUnscheduled方法:用于卸载JobDetail时调用

  3. triggerFinalized方法:当一个 Trigger 来到了再也不会触发的状态时调用这个方法。除非这个 Job 已设置成了持久性,否则它就会从 Scheduler 中移除。

  4. triggersPaused方法:Scheduler 调用这个方法是发生在一个 Trigger 或 Trigger 组被暂停时。假如是 Trigger 组的话,triggerName 参数将为 null。

  5. triggersResumed方法:Scheduler 调用这个方法是发生成一个 Trigger 或 Trigger 组从暂停中恢复时。假如是 Trigger 组的话,假如是 Trigger 组的话,triggerName 参数将为 null。参数将为 null。

  6. jobsPaused方法:当一个或一组 JobDetail 暂停时调用这个方法。

  7. jobsResumed方法:当一个或一组 Job 从暂停上恢复时调用这个方法。假如是一个 Job 组,jobName 参数将为 null。

  8. schedulerError方法:在 Scheduler 的正常运行期间产生一个严重错误时调用这个方法。

  9. schedulerStarted方法:当Scheduler 开启时,调用该方法

  10. schedulerInStandbyMode方法: 当Scheduler处于StandBy模式时,调用该方法

  11. schedulerShutdown方法:当Scheduler停止时,调用该方法

  12. schedulingDataCleared方法:当Scheduler中的数据被清除时,调用该方法。

13.shutdown(true):等待所有正在执行的job执行完毕,在关闭shceduler

14.shutdown(false):直接关闭scheduler

六:监听器的使用方法
任务监听器

HelloSchedulerDemoJobListener.java
	public class HelloSchedulerDemoJobListener {
		public static void main(String[] args) throws Exception {
		// 1:从工厂中获取任务调度的实例
	    Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
	
	    // 2:定义一个任务调度实例,将该实例与HelloJob绑定,任务类需要实现Job接口
	    JobDetail job = JobBuilder.newJob(HelloJobListener.class)
	    		.withIdentity("job1", "group1") // 定义该实例唯一标识
	    		.build();


          // 3:定义触发器 ,马上执行, 然后每5秒重复执行一次
          Trigger trigger = TriggerBuilder.newTrigger()
                  .withIdentity("trigger1", "group1") // 定义该实例唯一标识
                  .startNow()  // 马上执行
                  //.startAt(triggerStartTime) // 针对某个时刻执行
                  .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                      .repeatSecondlyForever(5)) // 每5秒执行一次 
                  .build();
    
          // 4:使用触发器调度任务的执行
          scheduler.scheduleJob(job, trigger);
    
          // 创建并注册一个全局的Job Listener
          scheduler.getListenerManager().addJobListener(new MyJobListener(), EverythingMatcher.allJobs());
    
          // 创建并注册一个指定任务的Job Listener
          // scheduler.getListenerManager().addJobListener(new MyJobListener(), 			  KeyMatcher.keyEquals(JobKey.jobKey("job1", "group1")));
          // 5:开启
          scheduler.start();
          // 关闭
          // scheduler.shutdown();
      }
    }

触发器监听器

HelloSchedulerDemoTriggerListener.java

	public class HelloSchedulerDemoTriggerListener {
	    public static void main(String[] args) throws Exception {
	        // 1:从工厂中获取任务调度的实例
	        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
	
	        // 2:定义一个任务调度实例,将该实例与HelloJob绑定,任务类需要实现Job接口
	        JobDetail job = JobBuilder.newJob(HelloJobListener.class)
	                .withIdentity("job1", "group1") // 定义该实例唯一标识
	                .build();


            // 3:定义触发器 ,马上执行, 然后每5秒重复执行一次
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity("trigger1", "group1") // 定义该实例唯一标识
                    .startNow()  // 马上执行
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .repeatSecondlyForever(5)) // 每5秒执行一次 
                    .build();
    
            // 4:使用触发器调度任务的执行
            scheduler.scheduleJob(job, trigger);
    
            // 创建并注册一个全局的Trigger Listener
            scheduler.getListenerManager().addTriggerListener(new MyTriggerListener("simpleTrigger"), EverythingMatcher.allTriggers());
    
            // 创建并注册一个局部的Trigger Listener
            // scheduler.getListenerManager().addTriggerListener(new MyTriggerListener("simpleTrigger"), KeyMatcher.keyEquals(TriggerKey.triggerKey("trigger1", "group1")));
    
            // 5:开启
            scheduler.start();
            // 关闭
            // scheduler.shutdown();
        }
     }

调度器监听器

HelloSchedulerDemoSchedulerListener.java

	public class HelloSchedulerDemoSchedulerListener {
	    public static void main(String[] args) throws Exception {
	        // 1:从工厂中获取任务调度的实例
	        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
	
	        // 2:定义一个任务调度实例,将该实例与HelloJob绑定,任务类需要实现Job接口
	        JobDetail job = JobBuilder.newJob(HelloJobListener.class)
	                .withIdentity("job1", "group1") // 定义该实例唯一标识
	                .build();


            // 3:定义触发器 ,马上执行, 然后每5秒重复执行一次
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity("trigger1", "group1") // 定义该实例唯一标识
                    .startNow()  // 马上执行
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .repeatSecondlyForever(5)) // 每5秒执行一次 
                    .build();
    
            // 4:使用触发器调度任务的执行
            scheduler.scheduleJob(job, trigger);
    
            // 创建SchedulerListener
            scheduler.getListenerManager().addSchedulerListener(new MySchedulerListener());
    
            // 移除对应的SchedulerListener
            // scheduler.getListenerManager().removeSchedulerListener(new MySchedulerListener());
    
            // 5:开启
            scheduler.start();
            // 延迟7秒后关闭
            Thread.sleep(7000);
            // 关闭
            scheduler.shutdown();
        }
     }

六:Quartzt配置自启动服务

配置文件applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="  
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd  
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd  
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd  
        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd  
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd  
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd  
        http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.1.xsd  
        http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.1.xsd  
        http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.1.xsd  
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd  
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

	   <bean id="workJob" class = "com.test.job"/> //序号1
//任务配置
    <bean id="workJobDetail"
        class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject">
            <ref bean="workJob" />  //序号1
        </property>
        <property name="targetMethod">
            <value>work</value>  //定时器的方法名
        </property>
    </bean>
	//触发器配置
	<bean id="workJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail">
            <ref bean="workJobDetail" />  //触发器引用的任务
        </property>
        <property name="cronExpression">
             <value>0 18 11 * * ?</value>  <!-- Cron表达式“0 59 23 * * ?”意为:每天23:59:00开始执行。  -->
        </property>
    </bean>
    //调度器配置
   <bean name="startQuertz" lazy-init="false" autowire="no"
        class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
            	<ref bean="workJobTrigger"/>  //执行触发器
            </list>
        </property>
    </bean>


public class WorkJob {
	
	protected final Logger logger = LoggerFactory.getLogger(getClass());

	
	
	public void work() {
		logger.info(("定时任务启动----------------"));
		
		
		
		logger.info("定时任务执行完毕----------------");
	}

</beans>``

七:Quartzt代码实现定时任务自启动

//这里写任务
public class HelloJobCronTrigger implements Job {
    protected final Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        // 定义时间
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = dateFormat.format(date);
        logger.info("111111111111111111111111111111");

        // 定义工作任务内容,可以是插入数据的方法、service层的调用
        System.out.println("进行数据库备份操作。当前任务执行的时间:" + dateString);
    }


}
//这里可以实现两个接口ApplicationListener接口或者CommandLineRunner接口都行
@Component
public class workJob implements ApplicationListener {

    @SneakyThrows
    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        System.out.println("任务调度开始==============任务调度开始");
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        //如果未初始化调度器的话,可能会报错
        scheduler.clear();
        // 2:定义一个任务调度实例,将该实例与HelloJob绑定,任务类需要实现Job接口
        JobDetail job = JobBuilder.newJob(HelloJobCronTrigger.class)
                .withIdentity("job4", "group4") // 定义该实例唯一标识
                .build();

        // 3:定义触发器 ,马上执行, 然后每5秒重复执行一次
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger4", "group4") // 定义该实例唯一标识
                .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))// 定义表达式
                .build();

        // 4:使用触发器调度任务的执行
        scheduler.scheduleJob(job, trigger);
        //开启定时器
        scheduler.start();
        System.out.println("任务调度结束==============任务调度结束");
    }

在这里插入图片描述
在这里插入图片描述


版权声明:本文为m0_47944994原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。