隨筆-95  評論-31  文章-10  trackbacks-0
          <一>、先引入依賴:
          未采用spring-boot-starter-quartz,直接采用quartz依賴
                  <dependency>
                      
          <groupId>org.quartz-scheduler</groupId>
                      
          <artifactId>quartz</artifactId>
                      
          <version>${quartz.version}</version> <!-- 2.2.2-->
                  
          </dependency>

          <二>、再看spring提供的五個類:
               1:JobDetailFactoryBean  --需關聯一個Job實現類
               2:MethodInvokingJobDetailFactoryBean  --無需關聯Job實現類,直接關聯一個自定義對象和需調度的方法即可調度
               3:SimpleTriggerFactoryBean  --一個簡單的觸發器,可設置間隔、次數等
               4:CronTriggerFactoryBean   --一個復雜觸發器,可設置各種時間、間隔、次數等配置
               5:SchedulerFactoryBean  --一個調度bean,可長存于spring容器內,@Autowired后在需要的地方可動態進行任務調度
               重點:適用場景,以上1-4只適用于spring容器啟動時進行任務調度,即調度都是提前設置好的、固定的調度參數,并不適用于動態場景,比如用戶在執行了某個操作后,再進行任務調度設置
               代碼示例:
               1):以下是@Configuration注解的類
              @Autowired
              
          private JobFactory jobFactory;

              
          /**
               * spring容器啟動就創建一個quartz調度器,其它地方通過這個bean根據業務生成觸發器和任務
               * 
          @return quartz調度器
               
          */
              @Bean
              
          public SchedulerFactoryBean createSchedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean){
                  SchedulerFactoryBean schedulerFactoryBean 
          = new SchedulerFactoryBean();
                  schedulerFactoryBean.setApplicationContextSchedulerContextKey(GlobalVariable.APPLICATION_CONTEXT_KEY);
                  schedulerFactoryBean.setStartupDelay(GlobalVariable.QUARTZ_NOTIFICATION_START_DELAY);
                  schedulerFactoryBean.setAutoStartup(GlobalVariable.QUARTZ_AUTO_START);
                  schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(GlobalVariable.QUARTZ_WAIT_FOR_JOBS_TO_COMPLETE_ON_SHUTDOWN);
                  schedulerFactoryBean.setJobFactory(jobFactory);
                  schedulerFactoryBean.setTriggers(cronTriggerFactoryBean.getObject());
                  
          return schedulerFactoryBean;
              }

              
          /**
               * 創建一個訂單過期的job
               *
               * 這種的只適合spring初始化容器的時候固定執行任務
               *
               * 
          @return 創建一個job
               
          */
              @Bean
              
          public JobDetailFactoryBean createBookingExpiredJob() {
                  JobDetailFactoryBean jobDetailFactoryBean 
          = new JobDetailFactoryBean();
                  jobDetailFactoryBean.setGroup(GlobalVariable.QUARTZ_NOTIFICATION_JOB_GROUP_NAME);
                  jobDetailFactoryBean.setName(GlobalVariable.QUARTZ_NOTIFICATION_BOOKING_EXPIRED_JOB_NAME);
                  jobDetailFactoryBean.setJobClass(JobTest.
          class);
                  Map
          <String, Object> dataAsMap = new HashMap<>();
                  dataAsMap.put(
          "booking","123");
                  jobDetailFactoryBean.setJobDataAsMap(dataAsMap);
                  
          return jobDetailFactoryBean;
              }

              
          /**
               * 創建一個訂單過期的trigger
               *
               * 這種的只適合spring初始化容器的時候固定執行任務
               *
               * 
          @return 創建一個trigger
               
          */
              @Bean
              
          public CronTriggerFactoryBean createBookingExpiredTrigger(JobDetailFactoryBean jobDetailFactoryBean) {
                  CronTriggerFactoryBean cronTriggerFactoryBean 
          = new CronTriggerFactoryBean();
                  cronTriggerFactoryBean.setGroup(GlobalVariable.QUARTZ_NOTIFICATION_JOB_GROUP_NAME);
                  cronTriggerFactoryBean.setName(GlobalVariable.QUARTZ_NOTIFICATION_BOOKING_EXPIRED_TRIGGER);
                  String cronExpression 
          = "5/3 * * * * ? *";
                  cronTriggerFactoryBean.setCronExpression(cronExpression);
                  cronTriggerFactoryBean.setTimeZone(TimeZone.getDefault());
                  cronTriggerFactoryBean.setJobDetail(jobDetailFactoryBean.getObject());
                  
          return cronTriggerFactoryBean;
              }

              
          /**
               * 這種的直接把方法作為job,不需要實現job接口
               
          */
              public MethoInvokingJobDetailFactoryBean
          createMethodInvokingJobDetailFactoryBean() {
                  MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean 
          = new MethodInvokingJobDetailFactoryBean();
                  methodInvokingJobDetailFactoryBean.setTargetClass(
          null);
                  methodInvokingJobDetailFactoryBean.setTargetMethod(
          "doJob");
                  methodInvokingJobDetailFactoryBean.setConcurrent(
          false);
                  methodInvokingJobDetailFactoryBean.setGroup(
          "notification");
                  methodInvokingJobDetailFactoryBean.setName(
          "notification-booking-expired");
                  return methodInvokingJobDetailFactoryBean;
              }
             
              
          private String getCronExpression(Date startDate) {
                  Calendar calendar 
          = DateUtils.toCalendar(startDate);
                  StringBuffer stringBuffer 
          = new StringBuffer(calendar.get(Calendar.SECOND)+"");
                  stringBuffer.append(
          " ");
                  stringBuffer.append(calendar.get(Calendar.MINUTE) 
          + "");
                  stringBuffer.append(
          " ");
                  stringBuffer.append(calendar.get(Calendar.HOUR_OF_DAY) 
          + "");
                  stringBuffer.append(
          " ");
                  stringBuffer.append(calendar.get(Calendar.DAY_OF_MONTH) 
          + "");
                  stringBuffer.append(
          " ");
                  stringBuffer.append(calendar.get(Calendar.MONTH)
          +1 + "");
                  stringBuffer.append(
          " ");
                  stringBuffer.append(
          "?");
                  stringBuffer.append(
          " ");
                  stringBuffer.append(calendar.get(Calendar.YEAR) 
          + "");
                  
          return stringBuffer.toString();
              }

               2): 具體執行的job,簡單示例:
          import org.quartz.Job;
          import org.quartz.JobExecutionContext;
          import org.quartz.JobExecutionException;

          public class JobTest implements Job {


              @Override
              
          public void execute(JobExecutionContext context) throws JobExecutionException {
                  System.out.println(
          "test----test");
              }
          }

                 3):這是自定義的JobFactory,這個類用于解決:上面JobTest里面如果有Autowired的spring容器bean,在execute方法里面調用時注入為null的問題
          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 JobFactory extends AdaptableJobFactory {

              @Autowired
              
          private AutowireCapableBeanFactory capableBeanFactory;


              @Override
              
          protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
                  Object jobInstance 
          = super.createJobInstance(bundle);
                  capableBeanFactory.autowireBean(jobInstance);
                  
          return jobInstance;
              }
          }
                以上在spring容器啟動時候,就會從第5秒開始每3秒運行一次、運行結果
          以上是spring容器啟動后,進行任務固定調度配置的運行,但是業務中一般都是動態創建job和trigger
                                                                                                                             華麗的分割線


          <三>:以下是動態創建job和trigger:
          代碼示例:
                   1):@Configuration注解的類里面
              @Autowired
              
          private JobFactory jobFactory;

              
          /**
               * spring容器啟動就創建一個quartz調度器,其它地方通過這個bean根據業務生成觸發器和任務
               * 
          @return quartz調度器
               
          */
              @Bean
              
          public SchedulerFactoryBean createSchedulerFactoryBean(){
                  SchedulerFactoryBean schedulerFactoryBean 
          = new SchedulerFactoryBean();
                  schedulerFactoryBean.setApplicationContextSchedulerContextKey(GlobalVariable.APPLICATION_CONTEXT_KEY);
                  schedulerFactoryBean.setStartupDelay(GlobalVariable.QUARTZ_NOTIFICATION_START_DELAY);
                  schedulerFactoryBean.setAutoStartup(GlobalVariable.QUARTZ_AUTO_START);
                  schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(GlobalVariable.QUARTZ_WAIT_FOR_JOBS_TO_COMPLETE_ON_SHUTDOWN);
                  schedulerFactoryBean.setJobFactory(jobFactory);
                  
          return schedulerFactoryBean;
              }
             
                 2): 具體執行的job,簡單示例
          public class NotificationJobService implements Job {

              
          private static final Logger LOGGER = LoggerFactory.getLogger(NotificationJobService.class);

              @Autowired
              
          private IMOpenfireServer imOpenfireServer;

              @Override
              
          public void execute(JobExecutionContext context) throws JobExecutionException {
                  LOGGER.info(
          "whether booking request has expired!");

                  JobDetail jobDetail 
          = context.getJobDetail();
                  JobDataMap jobDataMap 
          = jobDetail.getJobDataMap();
                  Booking booking 
          = (Booking) jobDataMap.get("booking");
          }
          }

               3):這是自定義的JobFactory,這個類用于解決:上面NotificationJobService 里面如果有Autowired的spring容器bean,在execute方法里面調用時注入為null的問題
          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 JobFactory extends AdaptableJobFactory {

              @Autowired
              
          private AutowireCapableBeanFactory capableBeanFactory;


              @Override
              
          protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
                  Object jobInstance 
          = super.createJobInstance(bundle);
                  capableBeanFactory.autowireBean(jobInstance);
                  
          return jobInstance;
              }
          }

              4): 動態設置觸發器和任務,比如調用下面的startJob方法,就開始進行觸發器和任務配置并進行調度、代碼示例:
              @Autowired
              
          private SchedulerFactoryBean schedulerFactoryBean;


              
          public void startJob(Date startDate,Booking booking) {

                  JobDataMap jobDataMap 
          = new JobDataMap();
                  jobDataMap.put(
          "booking",booking);
                  
          //創建一個job
                  JobDetail jobDetail = JobBuilder.newJob(NotificationJobService.class).setJobData(jobDataMap).build();
                  
          //創建一個trigger
                  Trigger trigger = TriggerBuilder.newTrigger().startAt(startDate).forJob(jobDetail).build();

                  
          try {
                      schedulerFactoryBean.getScheduler().scheduleJob(jobDetail,trigger);
                  } 
          catch (SchedulerException e) {
                      LOGGER.error(
          "schedule NotificationJob failed! {}",e);
                  }
              }

          以上就是動態設置調度任務的過程。

          完!


          posted on 2017-12-27 18:18 朔望魔刃 閱讀(2028) 評論(0)  編輯  收藏 所屬分類: java
          主站蜘蛛池模板: 澎湖县| 通海县| 论坛| 政和县| 永济市| 桑日县| 玉环县| 陇西县| 岚皋县| 班玛县| 房产| 定襄县| 开鲁县| 南康市| 荆州市| 海盐县| 安仁县| 西乌珠穆沁旗| 武平县| 大同县| 宁夏| 哈尔滨市| 淮安市| 新竹县| 汕头市| 承德县| 枝江市| 互助| 吉安县| 小金县| 阿坝| 乐平市| 阳江市| 藁城市| 吴江市| 唐河县| 崇州市| 深圳市| 水城县| 黔江区| 泉州市|