1、Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。这里我介绍quartz的两种方式。我这里搭建的框架是采用springboot、spring-data-jpa、mysql、quartz的方式来实现。

2、这里介绍的两种方式是:动态扫描的方式执行和注解的方式。

  至于 的配置方式可以参考:http://www.cnblogs.com/ll409546297/p/7157702.html

3、动态扫描的方式

  1)基本的目录结构

  

  2)需要的基础包:pom.

<?  version="1.0" encoding="UTF-8"?><project  ns="http://maven.apache.org/POM/4.0.0"          ns:xsi="http://www.w3.org/2001/ Schema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>com.troy</groupId>    <artifactId>springbootquartz</artifactId>    <version>1.0-SNAPSHOT</version>    <build>        <plugins>            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-compiler-plugin</artifactId>                <configuration>                    <source>1.8</source>                    <target>1.8</target>                </configuration>            </plugin>        </plugins>    </build>    <parent>        <groupId>org.spring work.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>1.5.7.RELEASE</version>    </parent>    <dependencies>        <dependency>            <groupId>org.spring work.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>            <version>1.5.7.RELEASE</version>        </dependency>        <dependency>            <groupId>org.spring work.boot</groupId>            <artifactId>spring-boot-starter-data-jpa</artifactId>            <version>1.5.7.RELEASE</version>        </dependency>        <dependency>            <groupId>org.quartz-scheduler</groupId>            <artifactId>quartz</artifactId>            <version>2.3.0</version>        </dependency>        <dependency>            <groupId>org.quartz-scheduler</groupId>            <artifactId>quartz-jobs</artifactId>            <version>2.3.0</version>        </dependency>        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>            <version>5.1.9</version>        </dependency>        <dependency>            <groupId>org.spring work</groupId>            <artifactId>spring-context-support</artifactId>            <version>4.3.11.RELEASE</version>        </dependency>    </dependencies></project>

  3)基本的yml配置application.yml  

server:  port: 8080spring:  datasource:    driver-class-name: com.mysql.jdbc.Driver    url: jdbc:mysql://localhost:3306/model?useUnicode=true&amp;characterEncoding=utf8    username: root    password: root  jpa:    hibernate:      ddl-auto: update    show-sql: true

  4)任务配置:TaskConfiguration.class

@Configuration@EnableSchedulingpublic class TaskConfiguration {    @Bean    public SchedulerFactoryBean schedulerFactoryBean(){        return new SchedulerFactoryBean();    }}

  5)实体需要的基础配置:ScheduleJob.class

@Entity@Tablepublic class ScheduleJob {    @Id    @GeneratedValue(strategy = GenerationType.AUTO)    private Long id;    private String jobName;    private String cron ;    private String springId;    private String methodName;    private String jobStatus;    public Long getId() {        return id;    }    public void setId(Long id) {        this.id = id;    }    public String getJobName() {        return jobName;    }    public void setJobName(String jobName) {        this.jobName = jobName;    }    public String getCron () {        return cron ;    }    public void setCron (String cron ) {        this.cron  = cron ;    }    public String getSpringId() {        return springId;    }    public void setSpringId(String springId) {        this.springId = springId;    }    public String getMethodName() {        return methodName;    }    public void setMethodName(String methodName) {        this.methodName = methodName;    }    public String getJobStatus() {        return jobStatus;    }    public void setJobStatus(String jobStatus) {        this.jobStatus = jobStatus;    }}

  6)基础数据访问配置和数据访问层:

@NoRepositoryBeanpublic interface  Repository<T,I extends Serializable> extends PagingAndSortingRepository<T,I>, JpaSpecificationExecutor<T> {}
public interface ScheduleJobRepository extends  Repository<ScheduleJob,Long> {    List<ScheduleJob> findAllByJobStatus(String jobStatus);}

  7)SpringUtil.class

@Componentpublic class SpringUtil implements BeanFactoryPostProcessor {    private static ConfigurableListableBeanFactory beanFactory;    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {        this.beanFactory = beanFactory;    }    public static   getBean(String name) {        return beanFactory.getBean(name);    }    public static <T> T getBean(Class<T> clazz){        return beanFactory.getBean(clazz);    }}

  8)任务的调度工厂(主要是实现具体的执行)QuartzFactory.class

public class QuartzFactory implements Job {    @Override    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {        //获取调度数据        ScheduleJob scheduleJob = (ScheduleJob) jobExecutionContext.getMergedJobDataMap().get("scheduleJob");        //获取对应的Bean            = SpringUtil.getBean(scheduleJob.getSpringId());        try {            //利用反射执行对应方法            Method method =  .getClass().getMethod(scheduleJob.getMethodName());            method.invoke( );        } catch (Exception e) {            e.printStackTrace();        }    }}

  9)具体的任务调度以及触发设置:TaskServiceImpl.class(略过接口)

@Service@Transactionalpublic class TaskServiceImpl implements ITaskService {    @Autowired    private SchedulerFactoryBean schedulerFactoryBean;    @Autowired    private ScheduleJobRepository scheduleJobRepository;    @Override    public void timingTask() {        //查询数据库是否存在需要定时的任务        List<ScheduleJob> scheduleJobs = scheduleJobRepository.findAllByJobStatus("1");        if (scheduleJobs != null) {            scheduleJobs.forEach(this::execute);        }    }    //添加任务    private void execute(ScheduleJob scheduleJob){        try {            //声明调度器            Scheduler scheduler = schedulerFactoryBean.getScheduler();            //添加触发调度名称            TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName());            //设置触发时间            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCron ());            //触发建立            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();            //添加作业名称            JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName());            //建立作业            JobDetail jobDetail = JobBuilder.newJob(QuartzFactory.class).withIdentity(jobKey).build();            //传入调度的数据,在QuartzFactory中需要使用            jobDetail.getJobDataMap().put("scheduleJob",scheduleJob);            //调度作业            scheduler.scheduleJob(jobDetail,trigger);        } catch (Exception e) {            throw new RuntimeException(e);        }    }}

  10)然后设置开机启动执行:TaskSchedule.class

@Componentpublic class TaskSchedule implements CommandLineRunner{    @Autowired    private ITaskService taskService;    /**     * 任务调度开始     * @param strings     * @throws Exception     */    @Override    public void run(String... strings) throws Exception {        System.out.println("任务调度开始==============任务调度开始");        taskService.timingTask();        System.out.println("任务调度结束==============任务调度结束");    }}

这里基础的配置就算完成了,然后就是在数据库进行相关的配置,项目启动的时候就开始扫描对应的表来执行具体的任务。

这里我写了一下简单的例子来实现。

  1)需要执行的方法:TaskInfoServiceImpl.class(略过接口)

@Service("taskInfo")@Transactionalpublic class TaskInfoServiceImpl implements ITaskInfoService {    @Override    public void execute() {        System.out.println("任务执行开始===============任务执行开始");        System.out.println(new Date());        System.out.println("任务执行结束===============任务执行结束");    }}

  2)数据库的配置(我这里测试用的每分钟0点执行)

  

测试结果:

4、注解的方式

  1)注解的方式相对动态配置来说简单的多,但是不便于管理。注解的方式需要的基础包,和上面基本上差不多

  2)这里我写了一下简单的例子来实现:TaskExcuteServiceImpl.class

@Service@Transactionalpublic class TaskExcuteServiceImpl implements ITaskExcuteService {    @Scheduled(cron = "30 * * * * ?")    @Override    public void excute() {        System.out.println("注解执行开始==============注解执行开始");        System.out.println(new Date());        System.out.println("注解执行结束==============注解执行结束");    }}

  3)测试结果为:

  

 

 

5、有需要源码的可以自己下载:https://pan.baidu.com/s/1pLSLdTT

收藏 打印