• 利用quartz实现定时调度


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

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

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

    3、动态扫描的方式

      1)基本的目录结构

      

      2)需要的基础包:pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-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.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.7.RELEASE</version>
        </parent>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>1.5.7.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.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.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>4.3.11.RELEASE</version>
            </dependency>
        </dependencies>
    </project>

      3)基本的yml配置application.yml  

    server:
      port: 8080
    spring:
      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
    @EnableScheduling
    public class TaskConfiguration {
    
        @Bean
        public SchedulerFactoryBean schedulerFactoryBean(){
            return new SchedulerFactoryBean();
        }
    }

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

    @Entity
    @Table
    public class ScheduleJob {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
        private String jobName;
        private String cronExpression;
        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 getCronExpression() {
            return cronExpression;
        }
    
        public void setCronExpression(String cronExpression) {
            this.cronExpression = cronExpression;
        }
    
        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)基础数据访问配置和数据访问层:

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

      7)SpringUtil.class

    @Component
    public class SpringUtil implements BeanFactoryPostProcessor {
    
        private static ConfigurableListableBeanFactory beanFactory;
    
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            this.beanFactory = beanFactory;
        }
    
        public static Object 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
            Object object = SpringUtil.getBean(scheduleJob.getSpringId());
            try {
                //利用反射执行对应方法
                Method method = object.getClass().getMethod(scheduleJob.getMethodName());
                method.invoke(object);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }

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

    @Service
    @Transactional
    public 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.getCronExpression());
                //触发建立
                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

    @Component
    public 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")
    @Transactional
    public 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
    @Transactional
    public 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

  • 相关阅读:
    【建兰普及模拟赛第一场】20181023
    【Uva11400 Lighting System Design】动态规划
    【洛谷 P2388 阶乘之乘】模拟
    【Uva1025 A Spy in the Metro】动态规划
    【洛谷P2028 龙兄摘苹果】动态规划
    【洛谷P1507 NASA的食物计划】动态规划
    【洛谷P1795 无穷的序列_NOI导刊2010提高(05)】模拟
    【洛谷P1281 书的复制】二分+动态规划
    【洛谷P4933 大师】动态规划
    「GXOI / GZOI2019」旧词
  • 原文地址:https://www.cnblogs.com/ll409546297/p/7793877.html
Copyright © 2020-2023  润新知