溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

SpringBoot 定時任務(wù)的實現(xiàn)

發(fā)布時間:2020-08-07 16:23:13 來源:網(wǎng)絡(luò) 閱讀:3005 作者:飛鳥如林 欄目:開發(fā)技術(shù)

介紹兩種實現(xiàn)方式;配置實現(xiàn)和讀取數(shù)據(jù)庫定時任務(wù)配置實現(xiàn)。

配置實現(xiàn)比較簡單。直接擼代碼:

package com;

import java.util.Properties;

import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportResource;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@SpringBootApplication@ImportResource("classpath:/config.xml")
br/>@ImportResource("classpath:/config.xml")
@ComponentScan
@EnableTransactionManagement(proxyTargetClass = true) @MapperScan({"com.*.model.*.mapper","com.*.task"})
br/>@MapperScan({"com.*.model.*.mapper","com.*.task"})
public class StartApplication {

public static void main(String[] args) {
    SpringApplication.run(StartApplication.class, args);
}

@Bean
public DatabaseIdProvider getDatabaseIdProvider() {

}

}注:在啟動類上加注解
@EnableScheduling
br/>注:在啟動類上加注解
@EnableScheduling
其他地方無需關(guān)注。

定時任務(wù)配置類:
package com.*.task;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Service
public class RunTaskConfig {

private static final SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
//初始延遲1秒,每隔2秒
@Scheduled(fixedRateString = "2000",initialDelay = 1000)
public void testFixedRate(){
    System.out.println("fixedRateString,當前時間:" +format.format(new Date()));
}

//每次執(zhí)行完延遲2秒
@Scheduled(fixedDelayString= "2000")
public void testFixedDelay(){
    System.out.println("fixedDelayString,當前時間:" +format.format(new Date()));
}
//每隔3秒執(zhí)行一次
@Scheduled(cron="0/3 * * * * ?")
public void testCron(){
    System.out.println("cron,當前時間:" +format.format(new Date()));
}

}

配置完成,項目啟動后配置的定時任務(wù)會自動執(zhí)行。

Springboot 定時任務(wù) 的數(shù)據(jù)庫實現(xiàn)方式:
數(shù)據(jù)表實體
id , 執(zhí)行類, 執(zhí)行方法, 是否生效, 時間表達式;

SpringBoot 定時任務(wù)實現(xiàn)原理:啟動Spring 會掃描@Scheduled 注解,讀取注解配置信息。
獲取定時任務(wù),解析,注冊成可執(zhí)行的定時任務(wù)。

數(shù)據(jù)庫活動定時任務(wù)實現(xiàn)具體代碼如下
package com.tansun.task;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.ScheduledExecutorService;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.NamedBeanHolder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.CronTask;
import org.springframework.scheduling.config.ScheduledTask;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.support.ScheduledMethodRunnable;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import com.tansun.model.system.dao.RunTaskDao;
import com.tansun.model.system.dao.RunTaskDaoImpl;
import com.tansun.model.system.dao.RunTaskSqlBulider;
import com.tansun.model.system.entity.RunTask;
import com.tansun.web.framework.util.BeanUtil;
/***

  • 定時任務(wù)啟動類,從數(shù)據(jù)庫讀取定時任務(wù)配置。監(jiān)控定時任務(wù)運行。
  • @author kangx
    */
    @Component("BeanDefineConfigue")
    public class EventListen implements ApplicationListener<ContextRefreshedEvent>, ApplicationContextAware{

    public static final String DEFAULT_TASK_SCHEDULER_BEAN_NAME = "taskScheduler";

    protected final Log logger = LogFactory.getLog(getClass());
    // 任務(wù)調(diào)度對象引用
    private Object scheduler;

    private String beanName;

    private BeanFactory beanFactory;
    // 配置環(huán)境上下文信息
    private ApplicationContext applicationContext;
    // 任務(wù)調(diào)度注冊中心,監(jiān)控定時任務(wù),設(shè)置定時任務(wù)啟動觸發(fā)器。
    private final ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar();

    // 定時任務(wù)執(zhí)行體
    private final Map<Object, Set<ScheduledTask>> scheduledTasks =
    new IdentityHashMap<Object, Set<ScheduledTask>>(16);

    public Object getScheduler() {
    return scheduler;
    }

    public void setScheduler(Object scheduler) {
    this.scheduler = scheduler;
    }
    //EmbeddedValueResolver embeddedValueResolver=new EmbeddedValueResolver(null);@Override
    br/>@Override

    try {
        RunTaskDao runTaskDao = BeanUtil.getBean(RunTaskDaoImpl.class);
        RunTaskSqlBulider runTaskSqlBulider = new RunTaskSqlBulider();
        //查找啟動狀態(tài)的定時任務(wù)
        runTaskSqlBulider.andIsWorkEqualTo("1");
        int count = runTaskDao.countBySqlBulider(runTaskSqlBulider);
        List<RunTask> list = new ArrayList<>(); 
        if(count>0){
            list = runTaskDao.selectListBySqlBulider(runTaskSqlBulider);
        }
        for(RunTask runtask:list){
            //定時任務(wù)對象解析,裝配及注冊
            processScheduled(runtask);
        }
        // 定時任務(wù)注冊,啟動定時任務(wù)
        finishRegistration();            
    
    } catch (Exception e) {
        e.printStackTrace();
    }

    }

    /**

    • 定時任務(wù)注冊
      */
      private void finishRegistration() {
      if (this.scheduler != null) {
      this.registrar.setScheduler(this.scheduler);
      }
      if (this.beanFactory instanceof ListableBeanFactory) {
      Map<String, SchedulingConfigurer> configurers =
      ((ListableBeanFactory) this.beanFactory).getBeansOfType(SchedulingConfigurer.class);
      for (SchedulingConfigurer configurer : configurers.values()) {
      configurer.configureTasks(this.registrar);
      }
      }
      if (this.registrar.hasTasks() && this.registrar.getScheduler() == null) {
      try {
      this.registrar.setTaskScheduler(resolveSchedulerBean(TaskScheduler.class, false));
      }
      catch (NoUniqueBeanDefinitionException ex) {
      try {
      this.registrar.setTaskScheduler(resolveSchedulerBean(TaskScheduler.class, true));
      }
      catch (NoSuchBeanDefinitionException ex2) {
      // 日志記錄
      ex2.printStackTrace();
      }
      }
      catch (NoSuchBeanDefinitionException ex) {
      // Search for ScheduledExecutorService bean next...
      try {
      this.registrar.setScheduler(resolveSchedulerBean(ScheduledExecutorService.class, false));
      }
      catch (NoUniqueBeanDefinitionException ex2) {
      try {
      this.registrar.setScheduler(resolveSchedulerBean(ScheduledExecutorService.class, true));
      }
      catch (NoSuchBeanDefinitionException ex3) {
      // 日志記錄
      ex3.printStackTrace();
      }
      }
      catch (NoSuchBeanDefinitionException ex2) {
      // 異常日志
      ex2.printStackTrace();
      }
      }
      }
      this.registrar.afterPropertiesSet();
      }
      private <T> T resolveSchedulerBean(Class<T> schedulerType, boolean byName) {
      if (byName) {
      T scheduler = this.beanFactory.getBean(DEFAULT_TASK_SCHEDULER_BEAN_NAME, schedulerType);
      if (this.beanFactory instanceof ConfigurableBeanFactory) {
      ((ConfigurableBeanFactory) this.beanFactory).registerDependentBean(
      DEFAULT_TASK_SCHEDULER_BEAN_NAME, this.beanName);
      }
      return scheduler;
      }
      else if (this.beanFactory instanceof AutowireCapableBeanFactory) {
      NamedBeanHolder<T> holder = ((AutowireCapableBeanFactory) this.beanFactory).resolveNamedBean(schedulerType);
      if (this.beanFactory instanceof ConfigurableBeanFactory) {
      ((ConfigurableBeanFactory) this.beanFactory).registerDependentBean(
      holder.getBeanName(), this.beanName);
      }
      return holder.getBeanInstance();
      }
      else {
      return this.beanFactory.getBean(schedulerType);
      }
      }

    /**

    • 定時任務(wù)裝配
    • @throws ClassNotFoundException
    • @throws SecurityException
    • @throws NoSuchMethodException
      */
      protected void processScheduled(RunTask runTask) throws Exception{
      try {
      Class clazz = Class.forName(runTask.getExecuteClass());
      Object bean = clazz.newInstance();
      Method method = clazz.getMethod(runTask.getExecuteMethod(), null);
      Method invocableMethod = AopUtils.selectInvocableMethod(method, clazz);
      Runnable runnable = new ScheduledMethodRunnable(bean, invocableMethod);
      boolean processedSchedule = false;

      Set<ScheduledTask> tasks = new LinkedHashSet<ScheduledTask>(4);
      String cron = runTask.getTimeExpression();
      if (StringUtils.hasText(cron)) {
          processedSchedule = true;
          String zone = "";
          TimeZone timeZone;
          if (StringUtils.hasText(zone)) {
              timeZone = StringUtils.parseTimeZoneString(zone);
          }
          else {
              timeZone = TimeZone.getDefault();
          }
          tasks.add(this.registrar.scheduleCronTask(new CronTask(runnable, new CronTrigger(cron, timeZone))));
      }
      // Finally register the scheduled tasks
      synchronized (this.scheduledTasks) {
          Set<ScheduledTask> registeredTasks = this.scheduledTasks.get(bean);
          if (registeredTasks == null) {
              registeredTasks = new LinkedHashSet<ScheduledTask>(4);
              this.scheduledTasks.put(bean, registeredTasks);
          }
          registeredTasks.addAll(tasks);
      }

      }
      catch (IllegalArgumentException ex) {
      // 日志
      ex.printStackTrace();
      }
      }
      /**

    • 獲取環(huán)境上下文信息*/
      @Override
      br/>*/
      @Override
      this.applicationContext = applicationContext;
      if (this.beanFactory == null) {
      this.beanFactory = applicationContext;
      }
      }
      }
向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI