spring boot2 integration (four) timed tasks Scheduled Quartz and persistence

spring boot2 integration (four) timed tasks Scheduled Quartz and persistence

Before entering the main text, I would like to introduce all the timing tasks that can be realized by java. In fact, this is also the idea of low-level implementation.

The approximate directory of this tutorial:

  1. Thread waits for timing tasks
  2. Realize timing tasks with Timer
  3. Realize timing tasks with ScheduledExecutorService
  4. Quartz timed task framework stand-alone application
  5. spingboot2 integrates Scheduled
  6. spingboot2 integrates the Quartz framework to persist timing tasks

###1. Thread waits for timing tasks

package com.fantj.myScheduled;

/**
 * Created by Fant.J.
 */
public class Test {
    public static void main(String[] args) {
        Thread thread = new Thread(()->{
            while (true) {
                System.out.println(" ");
                try {
                    Thread.sleep(1000 * 10);  //
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

 

Everyone can see from the code that if the task is complicated, it is quite troublesome, and there is also the risk of memory leakage, and it is out of control (uncontrollable).

Let's look at a relatively simple one.

###2. Timer

package com.fantj.myScheduled;

import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by Fant.J.
 */
public class Test {
    public static void main(String[] args) {

        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println("TimerTask is called!");
            }
        };

        Timer timer = new Timer();
       /*
         *   1     2 3 
         */
        timer.schedule(task, 0, 1000 * 3);
        timer.scheduleAtFixedRate(task, 0, 1000 * 3);
    }
}

 

Pay attention to the two methods called by the timer above: 1. Schedule, if the first execution is delayed, the subsequent task execution time will be based on the actual execution time of the last task. 2. ScheduleAtFixedRate, if the first execution is delayed , The execution time of subsequent tasks will be based on the time when the previous task started (synchronization needs to be considered)

If you let me say vulgarly, the first is to wait until the task is completed before starting the timing, and the second is to start timing when the task starts to run.

Let's take a look at the underlying implementation of Timer

public void schedule(TimerTask task, Date firstTime, long period) {
        if (period <= 0)
            throw new IllegalArgumentException("Non-positive period.");
        sched(task, firstTime.getTime(), -period);
    }
 

Then look at the TimerTask class

public abstract class TimerTask implements Runnable {
      public abstract void run();
    ...
}
 

You can probably see that it is also a thread implementation.

######Timer also has disadvantages:

When multiple threads are processing timed tasks in parallel, when the Timer runs multiple TimeTasks, as long as one of them does not catch the thrown exception, the other tasks will automatically terminate running. Using ScheduledExecutorService does not have this problem.

###3. Then we will study ScheduledExecutorService

package com.fantj.myScheduled;

/**
 * Created by Fant.J.
 */
public class Test {
    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("ScheduledExecutorService Task is called!");
            }
        };
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
       // 1  2 
       //     3  4 
        service.scheduleAtFixedRate(runnable, 0, 3, TimeUnit.SECONDS);
    }
}

 

This one. . Not much to say about the implementation principle, the Executors thread pool has appeared.

###Quartz Why does the timing task framework have a timing task framework? Everyone carefully observes the previous implementation cases. No timing task is controllable, which is particularly unfriendly to developers. Quartz is more nb. Let me take a look at some of its methods: Let me first introduce the working principle of Quartz. JobDetail is to write timing task logic, Trigger is a trigger to define cron and execution times.

    String getSchedulerName() throws SchedulerException;

    String getSchedulerInstanceId() throws SchedulerException;

    SchedulerContext getContext() throws SchedulerException;

    void start() throws SchedulerException;

    void startDelayed(int var1) throws SchedulerException;

    boolean isStarted() throws SchedulerException;

    void standby() throws SchedulerException;

    boolean isInStandbyMode() throws SchedulerException;

    void shutdown() throws SchedulerException;

    void shutdown(boolean var1) throws SchedulerException;

    boolean isShutdown() throws SchedulerException;

    SchedulerMetaData getMetaData() throws SchedulerException;

    List<JobExecutionContext> getCurrentlyExecutingJobs() throws SchedulerException;

    void setJobFactory(JobFactory var1) throws SchedulerException;

    ListenerManager getListenerManager() throws SchedulerException;

    Date scheduleJob(JobDetail var1, Trigger var2) throws SchedulerException;

    Date scheduleJob(Trigger var1) throws SchedulerException;

    void scheduleJobs(Map<JobDetail, Set<? extends Trigger>> var1, boolean var2) throws SchedulerException;

    void scheduleJob(JobDetail var1, Set<? extends Trigger> var2, boolean var3) throws SchedulerException;

    boolean unscheduleJob(TriggerKey var1) throws SchedulerException;

    boolean unscheduleJobs(List<TriggerKey> var1) throws SchedulerException;

    Date rescheduleJob(TriggerKey var1, Trigger var2) throws SchedulerException;

    void addJob(JobDetail var1, boolean var2) throws SchedulerException;

    void addJob(JobDetail var1, boolean var2, boolean var3) throws SchedulerException;

    boolean deleteJob(JobKey var1) throws SchedulerException;

    boolean deleteJobs(List<JobKey> var1) throws SchedulerException;

    void triggerJob(JobKey var1) throws SchedulerException;

    void triggerJob(JobKey var1, JobDataMap var2) throws SchedulerException;

    void pauseJob(JobKey var1) throws SchedulerException;

    void pauseJobs(GroupMatcher<JobKey> var1) throws SchedulerException;

    void pauseTrigger(TriggerKey var1) throws SchedulerException;

    void pauseTriggers(GroupMatcher<TriggerKey> var1) throws SchedulerException;

    void resumeJob(JobKey var1) throws SchedulerException;

    void resumeJobs(GroupMatcher<JobKey> var1) throws SchedulerException;

    void resumeTrigger(TriggerKey var1) throws SchedulerException;

    void resumeTriggers(GroupMatcher<TriggerKey> var1) throws SchedulerException;

    void pauseAll() throws SchedulerException;

    void resumeAll() throws SchedulerException;

    List<String> getJobGroupNames() throws SchedulerException;

    Set<JobKey> getJobKeys(GroupMatcher<JobKey> var1) throws SchedulerException;

    List<? extends Trigger> getTriggersOfJob(JobKey var1) throws SchedulerException;

    List<String> getTriggerGroupNames() throws SchedulerException;

    Set<TriggerKey> getTriggerKeys(GroupMatcher<TriggerKey> var1) throws SchedulerException;

    Set<String> getPausedTriggerGroups() throws SchedulerException;

    JobDetail getJobDetail(JobKey var1) throws SchedulerException;

    TriggerState getTriggerState(TriggerKey var1) throws SchedulerException;

    void resetTriggerFromErrorState(TriggerKey var1) throws SchedulerException;

    boolean interrupt(String var1) throws UnableToInterruptJobException;

    boolean checkExists(JobKey var1) throws SchedulerException;

 

It can be seen that basically the control of timing tasks can be said to be very complete. Including additions, deletions, revisions, etc. The following is an example. Of course, you need to download the necessary dependent jars. You can download this by yourself from Baidu, without focusing on explanation.

package com.fantj.myScheduled;

/**
 * Created by Fant.J.
 */
public class Test {
    public static void main(String[] args) {
        try {
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
            scheduler.start();

            JobDetail job = JobBuilder.newJob(Job.class)
                    .withIdentity("job", "group").build();

           // withIntervalInSeconds 
            SimpleTrigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity("trigger", "group").startNow()
                    .withSchedule(simpleSchedule().withIntervalInSeconds(3).repeatForever())
                    .build();

            scheduler.scheduleJob(job, trigger);

           //scheduler.shutdown();

        } catch (SchedulerException se) {
            se.printStackTrace();
        }
    }
}

    class Job implements org.quartz.Job {
        @Override
        public void execute(JobExecutionContext context) throws JobExecutionException {
            System.out.println("Quartz task is called!");
        }
}
 

spingboot2 integrates Scheduled

SpringBoot has built-in timed task Scheduled, and the operation can be described as particularly simple. It spring-boot-starter-webcan be achieved by importing dependent packages normally .

Scheduled first step

Add annotations to the restart class@EnableScheduling

package com.fantj;

@SpringBootApplication
@MapperScan("com.fantj.mapper")
@EnableScheduling //
public class MybatisApplication {

	public static void main(String[] args) {
		SpringApplication.run(MybatisApplication.class, args);
	}
}
 
Scheduled Step 2

Write Task. That is, timed tasks.

package com.fantj.myScheduled;

/**
 * scheduled  
 * Created by Fant.J.
 */
@Component
public class Task {


    @Scheduled(cron = "5 0 0 * * ?")
    public void scheduledTask1(){
        System.out.println("scheduledTask method run..");
    }

    @Scheduled(initialDelay =  1000 * 10,fixedDelay = 1000 * 5)
    public void scheduledTask2(){
        System.out.println("scheduledTask method run..");
    }

    @Scheduled(initialDelay =  1000 * 10,fixedDelay = 1000 * 5)
    public void test() throws Exception {
        for (int i = 0;i<20;i++){
            new MailSender()
                    .title("FantJ ")
                    .content(" ")
                    .contentType(MailContentTypeEnum.TEXT)
                    .targets(new ArrayList<String>(){{
                        add("xxxxxx@qq.com");
                    }})
                    .send();
            System.out.println(" "+i+" !");
        }
    }
}

 

The third method is an interface I wrote to send emails. You can refer to one of my articles Java Send QQ mail

######I introduce @Scheduledthe three (four) attributes of the annotations:

  • cron: Anyone who knows a little bit of Linux knows it. If you haven't heard of it, you can Baidu it yourself.

  • fixedRate and fixedDelay: These are very similar to the two Timer methods (rate and delay). If I say vulgarly, the first one is to time the task when it starts running, and the second is to wait until the task is finished before it starts.

  • initialDelay: The function of this attribute is to set the first execution delay time. It needs to be used with fixedDelay, fixedRate, and crop.

###Thinking of new problems

Although the above method has been improving, but imagine a situation, if the server that is executing a scheduled task hangs, how to find how many times it has been executed before. If we persist timed tasks to the database and maintain tasks like ordinary logical data, we will avoid all kinds of special situations encountered in the project.

spingboot2 integrates the Quartz framework to persist timing tasks

It is very troublesome to declare in advance, because we need to add ioc management (there are some notes, you can try to understand), and we need to create the data table that quartz needs to create. After that, it's like playing single machine (see above: Quartz timed task framework stand-alone application), playing quartz.

1. Import dependencies
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-jobs</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>

 

Prompt, this project is based on the springboot2 integrated mybatic project: https://www.jianshu.com/p/c15094bd1965

2. Quartz injects Spring IOC configuration

QuartzConfiguration.java

package com.fantj.quartz;

/**
 * quartz 
 * Created by Fant.J.
 */
@Configuration
@EnableScheduling
public class QuartzConfiguration
{
   /**
     *  org.springframework.scheduling.quartz.SpringBeanJobFactory
     *  
     */
    public static class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements
            ApplicationContextAware {

        private transient AutowireCapableBeanFactory beanFactory;

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

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

   /**
     *  
     * @param applicationContext spring 
     * @return
     */
    @Bean
    public JobFactory jobFactory(ApplicationContext applicationContext)
    {
       /**
         *    spring 
         * see {@link AutowiringSpringBeanJobFactory}
         */
        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
        jobFactory.setApplicationContext(applicationContext);
        return jobFactory;
    }

   /**
     *  
     *  quartz 
     * @param jobFactory  
     * @param dataSource  
     * @return
     * @throws Exception
     */
    @Bean(destroyMethod = "destroy",autowire = Autowire.NO)
    public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory, DataSource dataSource) throws Exception
    {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
       //spring job 
        schedulerFactoryBean.setJobFactory(jobFactory);
       //
        schedulerFactoryBean.setOverwriteExistingJobs(true);
       //2 
        schedulerFactoryBean.setStartupDelay(2);
       //
        schedulerFactoryBean.setAutoStartup(true);
       //
        schedulerFactoryBean.setDataSource(dataSource);
       //spring bean name
        schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContext");
       //
        schedulerFactoryBean.setConfigLocation(new ClassPathResource("/quartz.properties"));
        return schedulerFactoryBean;
    }
}

 

Look at the penultimate line of the code, a configuration file is needed, then...

quartz.properties configuration
# 
org.quartz.scheduler.instanceName = quartzScheduler

# 
org.quartz.scheduler.instanceId = AUTO

# 
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX

# MySQL 
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate

#quartz 
org.quartz.jobStore.tablePrefix = QRTZ_

# 
org.quartz.jobStore.isClustered = true
# 
org.quartz.jobStore.useProperties = false

# 
org.quartz.jobStore.clusterCheckinInterval = 20000

# 
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool

# 
org.quartz.threadPool.threadCount = 10

# 
org.quartz.threadPool.threadPriority = 5

# 
#org.quartz.threadPool.makeThreadsDaemons=true

# true
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

 

######Create a data sheet to tell you that you may not believe it, it needs the support of eleven data sheets.

#  
# In your Quartz properties file, you'll need to set   
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate  
#  
#  
# By: Ron Cordell - roncordell  
#  I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.  
  
DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;  
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;  
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;  
DROP TABLE IF EXISTS QRTZ_LOCKS;  
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;  
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;  
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;  
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;  
DROP TABLE IF EXISTS QRTZ_TRIGGERS;  
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;  
DROP TABLE IF EXISTS QRTZ_CALENDARS;  
  
CREATE TABLE QRTZ_JOB_DETAILS(  
SCHED_NAME VARCHAR(120) NOT NULL,  
JOB_NAME VARCHAR(200) NOT NULL,  
JOB_GROUP VARCHAR(200) NOT NULL,  
DESCRIPTION VARCHAR(250) NULL,  
JOB_CLASS_NAME VARCHAR(250) NOT NULL,  
IS_DURABLE VARCHAR(1) NOT NULL,  
IS_NONCONCURRENT VARCHAR(1) NOT NULL,  
IS_UPDATE_DATA VARCHAR(1) NOT NULL,  
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,  
JOB_DATA BLOB NULL,  
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))  
ENGINE=InnoDB;  
  
CREATE TABLE QRTZ_TRIGGERS (  
SCHED_NAME VARCHAR(120) NOT NULL,  
TRIGGER_NAME VARCHAR(200) NOT NULL,  
TRIGGER_GROUP VARCHAR(200) NOT NULL,  
JOB_NAME VARCHAR(200) NOT NULL,  
JOB_GROUP VARCHAR(200) NOT NULL,  
DESCRIPTION VARCHAR(250) NULL,  
NEXT_FIRE_TIME BIGINT(13) NULL,  
PREV_FIRE_TIME BIGINT(13) NULL,  
PRIORITY INTEGER NULL,  
TRIGGER_STATE VARCHAR(16) NOT NULL,  
TRIGGER_TYPE VARCHAR(8) NOT NULL,  
START_TIME BIGINT(13) NOT NULL,  
END_TIME BIGINT(13) NULL,  
CALENDAR_NAME VARCHAR(200) NULL,  
MISFIRE_INSTR SMALLINT(2) NULL,  
JOB_DATA BLOB NULL,  
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),  
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)  
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))  
ENGINE=InnoDB;  
  
CREATE TABLE QRTZ_SIMPLE_TRIGGERS (  
SCHED_NAME VARCHAR(120) NOT NULL,  
TRIGGER_NAME VARCHAR(200) NOT NULL,  
TRIGGER_GROUP VARCHAR(200) NOT NULL,  
REPEAT_COUNT BIGINT(7) NOT NULL,  
REPEAT_INTERVAL BIGINT(12) NOT NULL,  
TIMES_TRIGGERED BIGINT(10) NOT NULL,  
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),  
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)  
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))  
ENGINE=InnoDB;  
  
CREATE TABLE QRTZ_CRON_TRIGGERS (  
SCHED_NAME VARCHAR(120) NOT NULL,  
TRIGGER_NAME VARCHAR(200) NOT NULL,  
TRIGGER_GROUP VARCHAR(200) NOT NULL,  
CRON_EXPRESSION VARCHAR(120) NOT NULL,  
TIME_ZONE_ID VARCHAR(80),  
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),  
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)  
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))  
ENGINE=InnoDB;  
  
CREATE TABLE QRTZ_SIMPROP_TRIGGERS  
  (            
    SCHED_NAME VARCHAR(120) NOT NULL,  
    TRIGGER_NAME VARCHAR(200) NOT NULL,  
    TRIGGER_GROUP VARCHAR(200) NOT NULL,  
    STR_PROP_1 VARCHAR(512) NULL,  
    STR_PROP_2 VARCHAR(512) NULL,  
    STR_PROP_3 VARCHAR(512) NULL,  
    INT_PROP_1 INT NULL,  
    INT_PROP_2 INT NULL,  
    LONG_PROP_1 BIGINT NULL,  
    LONG_PROP_2 BIGINT NULL,  
    DEC_PROP_1 NUMERIC(13,4) NULL,  
    DEC_PROP_2 NUMERIC(13,4) NULL,  
    BOOL_PROP_1 VARCHAR(1) NULL,  
    BOOL_PROP_2 VARCHAR(1) NULL,  
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),  
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)   
    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))  
ENGINE=InnoDB;  
  
CREATE TABLE QRTZ_BLOB_TRIGGERS (  
SCHED_NAME VARCHAR(120) NOT NULL,  
TRIGGER_NAME VARCHAR(200) NOT NULL,  
TRIGGER_GROUP VARCHAR(200) NOT NULL,  
BLOB_DATA BLOB NULL,  
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),  
INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),  
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)  
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))  
ENGINE=InnoDB;  
  
CREATE TABLE QRTZ_CALENDARS (  
SCHED_NAME VARCHAR(120) NOT NULL,  
CALENDAR_NAME VARCHAR(200) NOT NULL,  
CALENDAR BLOB NOT NULL,  
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))  
ENGINE=InnoDB;  
  
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (  
SCHED_NAME VARCHAR(120) NOT NULL,  
TRIGGER_GROUP VARCHAR(200) NOT NULL,  
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))  
ENGINE=InnoDB;  
  
CREATE TABLE QRTZ_FIRED_TRIGGERS (  
SCHED_NAME VARCHAR(120) NOT NULL,  
ENTRY_ID VARCHAR(95) NOT NULL,  
TRIGGER_NAME VARCHAR(200) NOT NULL,  
TRIGGER_GROUP VARCHAR(200) NOT NULL,  
INSTANCE_NAME VARCHAR(200) NOT NULL,  
FIRED_TIME BIGINT(13) NOT NULL,  
SCHED_TIME BIGINT(13) NOT NULL,  
PRIORITY INTEGER NOT NULL,  
STATE VARCHAR(16) NOT NULL,  
JOB_NAME VARCHAR(200) NULL,  
JOB_GROUP VARCHAR(200) NULL,  
IS_NONCONCURRENT VARCHAR(1) NULL,  
REQUESTS_RECOVERY VARCHAR(1) NULL,  
PRIMARY KEY (SCHED_NAME,ENTRY_ID))  
ENGINE=InnoDB;  
  
CREATE TABLE QRTZ_SCHEDULER_STATE (  
SCHED_NAME VARCHAR(120) NOT NULL,  
INSTANCE_NAME VARCHAR(200) NOT NULL,  
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,  
CHECKIN_INTERVAL BIGINT(13) NOT NULL,  
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))  
ENGINE=InnoDB;  
  
CREATE TABLE QRTZ_LOCKS (  
SCHED_NAME VARCHAR(120) NOT NULL,  
LOCK_NAME VARCHAR(40) NOT NULL,  
PRIMARY KEY (SCHED_NAME,LOCK_NAME))  
ENGINE=InnoDB;  
  
CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);  
CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);  
  
CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);  
CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);  
CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);  
CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);  
CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);  
CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);  
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);  
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);  
CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);  
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);  
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);  
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);  
  
CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);  
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);  
CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);  
CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);  
CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);  
CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);  
  
commit;   
 

#####Alright, start writing timed task business

1. we need to customize a subclass of Job to write JobDetail

package com.fantj.quartz.notSpringFrame;

/**
 * quartz 
 */
public class MyJob implements Job {

    public MyJob(){}
    @Override
   //execute 
    public void execute(JobExecutionContext arg0) throws JobExecutionException
    {
        DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        System.out.println(" Quartz"+ df.format(Calendar.getInstance().getTime()));
    }
}

 

Secondly, I am here to demonstrate how to inject and use timed tasks in ServiceImpl.

package com.fantj.service.impl;

/**
 * Created by Fant.J.
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

   // 
  @Autowired
  private Scheduler scheduler;

//    quartz    
    public void sendMail() throws Exception {
       //1 
        long startAtTime = System.currentTimeMillis() + 1000 * 60;
       //
        String name = UUID.randomUUID().toString();
       //
        String group = MyJob.class.getName();
       //
        JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity(name,group).build();
       //
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity(name,group).startAt(new Date(startAtTime)).build();
       //
        scheduler.scheduleJob(jobDetail, trigger);
    }
}

 

Still like playing quartz in a single machine, you need to pass in two objects (a JobDetail, a Trigger) task details and triggers. If you don t understand, there is a detailed introduction above. Well, when we start the project, we can see the console printing, and the quar_ and other tables in the database are automatically filled with the information of the timed task.

We probably just completed the persistence of quartz. As we said above, the highlight of quartz is mainly the controllability of timed tasks, so if you need to add, delete, modify and check timed tasks on the background management page. I recommend a blog to everyone, well written http://blog.csdn.net/u012907049/article/details/73801122

Thank you also to this author.

Finally, thank you all, this article is quite long.