SpringBoot 整合 Quartz 实现 JAVA 定时任务的动态配置

参考地址:https://mp.weixin.qq.com/s/3_8yfRMzpJ5ZrRTiOOeP5w

一、maven依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>

补充:此处采用的内嵌数据库H2+spring data jpa

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
<dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>

二、配置信息

1、application.yml

server:
  port: 8081
spring:
  datasource:
#数据库存储路径(./database/job表示和项目代码同级) url: jdbc:h2:.
/database/job driver-class-name: org.h2.Driver username: yzh password: 123456 jpa: database: h2 hibernate: ddl-auto: update show-sql: true h2: console: path: /h2-console enabled: true

2、配置类(QuartzConfig)

@Configuration
public class QuartzConfig {

    @Autowired
    private JobFactory jobFactory;

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        schedulerFactoryBean.setOverwriteExistingJobs(true);
        schedulerFactoryBean.setQuartzProperties(quartzProperties());
        schedulerFactoryBean.setJobFactory(jobFactory);
        return schedulerFactoryBean;
    }

    /**
     * 指定quartz.properties,可在配置文件中配置相关属性
     * @return
     * @throws IOException
     */
    public Properties quartzProperties() throws IOException {
        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
        propertiesFactoryBean.setLocation(new ClassPathResource("/config/quartz.properties"));
        propertiesFactoryBean.afterPropertiesSet();
        return propertiesFactoryBean.getObject();
    }

    /**
     * 创建schedule
     * @return
     * @throws IOException
     */
    @Bean(name = "scheduler")
    public Scheduler scheduler() throws IOException {
        return schedulerFactoryBean().getScheduler();
    }
}
View Code

3、实体类(SysTask)

@Entity
public class SysTask implements Serializable {
    private static final long serialVersionUID = -560378047531235168L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 任务名
     */
    private String jobName;

    /**
     * 任务描述
     */
    private String description;

    /**
     * cron表达式
     */
    private String cronExpression;

    /**
     * 任务执行时调用哪个类的方法 包名+类名
     */
    private String beanClass;

    /**
     * 任务状态
     */
    private String jobStatus;

    /**
     * 任务分组
     */
    private String jobGroup;

    /**
     * 创建者
     */
    private String createUser;

    /**
     * 创建时间
     */
    private Date createTime;

    /**
     * 更新者
     */
    private String updateUser;

    /**
     * 更新时间
     */
    private Date update_time;
View Code

对应的dao(ISysTaskDao

@Component
public interface ISysTaskDao extends JpaRepository<SysTask,Long> {
}

4、添加监听器(ScheduleJobInitListener)

项目启动时,初始化任务

@Component
@Order(1)
public class ScheduleJobInitListener implements CommandLineRunner {

    @Autowired
    private ISysTakService takService;

    @Override
    public void run(String... args) throws Exception {
        takService.initSchedule();
    }
}

5、读取数据库,加载scheduler调度器

(1)、获取数据库中的任务

@Service
public class SysTakServiceImpl implements ISysTakService {

    @Autowired
    private ISysTaskDao sysTaskDao;
    @Autowired
    private QuartzManager quartzManager;

    @Transactional(readOnly = true,propagation = Propagation.NOT_SUPPORTED)
    @Override
    public void initSchedule() throws Exception {
        //获取任务信息
        List<SysTask> all = sysTaskDao.findAll();
        /**
         * 正在运行的
         */
        for (SysTask sysTask : all) {
            if (JobStatusEnum.RUNNING.getStatus().equals(sysTask.getJobStatus())){
                quartzManager.addJob(sysTask);
            }
        }
    }
}

(2)、添加任务到Quartz调度器

@Component
public class QuartzManager {

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

    @Autowired
    private Scheduler scheduler;

    /**
     * 添加并启动任务
     * @param task
     */
    @SuppressWarnings("unchecked")
    public void addJob(SysTask task) throws Exception {
        //创建jobDetail实例,绑定job实现类
        Class<? extends Job> jobClass = (Class<? extends Job>) (Class.forName(task.getBeanClass()).newInstance()
                .getClass());
        JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(task.getJobName(), task.getJobGroup()).build();
        //定义调度触发规则
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity(task.getJobName(), task.getJobGroup())// 触发器key
                .startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND))
                .withSchedule(CronScheduleBuilder.cronSchedule(task.getCronExpression())).startNow().build();
        //把作业和触发器注册到任务调度中
        scheduler.scheduleJob(jobDetail,trigger);
        //启动
        if (!scheduler.isShutdown()){
            scheduler.start();
        }
    }
}

6、实例化job类,注入要运行的service

(1)、工厂类(JobFactory

@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;
    }
}

(2)、具体任务类

@DisallowConcurrentExecution //不允许多线程运行
@Component
public class HelloWorldJob implements Job {

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

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        JobKey key = jobExecutionContext.getJobDetail().getKey();
        LOGGER.info("任务【{}】-【{}】执行开始了--:{}",key.getName(),key.getGroup(),new Date());
    }
}

 源码地址:https://github.com/cqyzh/springboot_quartz

posted @ 2020-09-27 14:35  炫舞风中  阅读(1379)  评论(0编辑  收藏  举报