引言
在实际开发当中,java后端开发在处理各种各样的问题时,对一段逻辑或者功能,免不了会遇到定时操作,定时操作出现的频率也是相当的高,所以对定时器或者定时框架的使用作为一名开发者是必须要熟练掌握的,接下来笔者就自身经常使用的其中一种框架–quartz,下面做一个简单的介绍及基于springboot的配置!相对来说比较简单,由于是第二篇文章,先讲点简单的

1、quartz概述:

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 2.3.2
Quartz是一个完全由java编写的开源作业调度框架。不要让作业调度这个术语吓着你。尽管Quartz框架整合了许多额外功能, 但就其简易形式看,你会发现它易用得简直让人受不了!简单地创建一个实现org.quartz.Job接口的java类。Job接口包含唯一的方法:
public void execute(JobExecutionContext context)
throws JobExecutionException;
在你的Job接口实现类里面,添加一些逻辑到execute()方法。一旦你配置好Job实现类并设定好调度时间表,Quartz将密切注意剩余时间。当调度程序确定该是通知你的作业的时候,Quartz框架将调用你Job实现类(作业类)上的execute()方法并允许做它该做的事情。无需报告任何东西给调度器或调用任何特定的东西。仅仅执行任务和结束任务即可。如果配置你的作业在随后再次被调用,Quartz框架将在恰当的时间再次调用它。

2、代码层面快速使用springboot整合quartz框架

2.1、使用springboot的maven中pom文件引入quartz依赖(与slf4j-api同时引入),如果使用的是grandle,则用相应的依赖包即可

<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
   <groupId>org.quartz-scheduler</groupId>
   <artifactId>quartz</artifactId>
   <version>2.3.0</version>
   <exclusions>
      <exclusion>
         <artifactId>slf4j-api</artifactId>
         <groupId>org.slf4j</groupId>
      </exclusion>
   </exclusions>
</dependency>

2.2、手写quartz定时框架配置类

配置类代码技术说明:

  1. 创建job定时任务工厂方法,将定时业务类交给job工厂管理,配置类使用@configuration注解标识,使之能够被spring容器管理
    2 创建trigger定时触发工厂对象,将第一步创建的job工厂对象注入到trigger定时触发工厂中,使之完成指定job的定时触发工作,在此工厂中定义触发时间,使用cron表达式定义
  2. 创建scheduler任务调度器,是实际执行任务的任务调度器,用SchedulerFactoryBean封装,将job工厂和trigger工厂与scheduler绑定起来,这里的job对象由于在2-3中的quartzService业务中使用@autowired注解实现将业务方法自动注入,实际上并未交给spring容器进行管理,所以我们重写源码中createJobInstance方法,使其能够被spring容器进行有效的管理,具体代码看下面2-4
@Configuration
public class QuartzConfig {
   @Autowired 
   private Environment env;
   //private String propertiesName = "/properties/quartz.properties";
   //1.创建job
   @Bean
   public JobDetailFactoryBean jobDetailFactoryBean () {
      JobDetailFactoryBean factory = new JobDetailFactoryBean();
      factory.setJobClass(QuartzService.class);
      return factory;
   }
   
   //2.创建trigger
   @Bean
   public CronTriggerFactoryBean cronTriggerFactoryBean (JobDetailFactoryBean jobDetailFactoryBean) {
//    Properties properties = QuartzPropertiesConfig.readProperties(propertiesName);
//    String cron = properties.getProperty("cron");
      String cron = env.getProperty("cron");
      CronTriggerFactoryBean triggerFactory = new CronTriggerFactoryBean();
      triggerFactory.setJobDetail(jobDetailFactoryBean.getObject());
      triggerFactory.setCronExpression(cron);
      return triggerFactory;
   }
   @Bean
   //2.创建scheduler
   public SchedulerFactoryBean schedulerFactoryBean (CronTriggerFactoryBean cronTriggerFactoryBean, MyAdaptAbleJobFactory myAdaptAbleJobFactory) {
      SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
      schedulerFactory.setTriggers(cronTriggerFactoryBean.getObject());
      schedulerFactory.setJobFactory(myAdaptAbleJobFactory);
      return schedulerFactory;
   }
   
}

2.3、自定义所需定时运行的业务模块(quartzService模块)

模块说明:定义定时业务类,使其实现Job接口,重写execute方法,此方法中调用要执行的真实业务

public class QuartzService implements Job{

   @Autowired
   private ManuscriptRefresh manuscriptRefresh;
   @Autowired
   private ImageManuscriptRefresh imageManuscriptRefresh;
   @Override
   public void execute(JobExecutionContext context) throws JobExecutionException {
      try {
         //1.更新配置文件中指定的普通栏目redis缓存
         manuscriptRefresh.findManuscriptByChannelIdAndPageNum();
         //2.幻灯片栏目缓存更新
         imageManuscriptRefresh.findImage();
      } catch (Exception e) {
         
         e.printStackTrace();
      }
      
   }

}

2.4、重写quartz框架中job对象注入源码方法并使用@component注解交给spring容器进行管理

@Component("myAdaptAbleJobFactory")
public class MyAdaptAbleJobFactory extends AdaptableJobFactory{
   @Autowired
   private AutowireCapableBeanFactory autowireCapableBeanFactory;

   @Override
   protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
      Object obj = super.createJobInstance(bundle);
      this.autowireCapableBeanFactory.autowireBean(obj);//将obj注入给spring容器管理
      return obj;
   }
}

2.5、在springboot启动类中加入@EnableScheduler注解进行标识

@EnableCaching
@SpringBootApplication
@ServletComponentScan
@EnableScheduling
//public class SctyjapphtApplication {
//
// public static void main(String[] args) {
//          SpringApplication.run(SctyjapphtApplication.class, args);     
// }
//    
// }
public class TomcatApplication extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(TomcatApplication.class);
    }
    public static void main(String[] args){
            SpringApplication.run(TomcatApplication.class, args);     
    }
}

总结:
虽然配置看似简单,但是能否运用起来,还是要对quartz的源码做一定的了解和理解,这样在你实际的业务需求中才能融会贯通的使用,在上述代码中,本人是配合redis使用,要起到在服务提供前端相应的数据响应的同时呢,要定时刷新redis的缓存,有人会问,为什么缓存不用jdk自带的呢,那我告诉你,并不好用!jdk自带缓存机制对键的过期时间设置不友好,有点跑题,哈哈,今天就写到这,工作之余抽空分享,下篇讲讲微服务和GIS相关技术!