spring定时任务如何运行 schedule解析

简介: spring定时任务解析

网上关于spring自带的定时任务是怎么运行的文档很少,goole 百度了很久都没找到这块的文档,而集成quartz的文档很多,而spring如果单纯的只是运行定时任务是不需要quartz包的。下面是我自己研究出来的,有错见谅。

经过长时间的研究spirng的源码,发现如果仅仅只是在xml里配置定时任务或者通过注解来实现配置定时任务的话,无需依赖spring-context-support,这个包里所含的scheduling包都是为了集成quartz的,而spirng其实只用了spring-context的scheduling包。下面解读一下spring是如何解析我们的配置并且运行的

简单的配置一下定时任务

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:task="http://www.springframework.org/schema/task"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- job 的包 加载定时任务实现类-->
    <context:component-scan base-package="com.galaxy.fym.job"></context:component-scan>
    <!-- 任务调度器配置 配置任务线性池 pool-size
    指配的一个scheduled-tasks中所有的运行方法的线程总数
    不同的scheduled-tasks配置了相同的task:scheduler会有相同的总数限制,而不是和的限制-->
    <task:scheduler id="scheduler" pool-size="10" />
    <!-- 指定运行的方法和运行时间规则时间
    task:scheduler/@pool-size:调度线程池的大小,调度线程在被调度任务完成前不会空闲
    task:scheduled/@cron:cron表达式,注意,若上次任务未完成,即使到了下一次调度时间,任务也不会重复调度 -->
    <task:scheduled-tasks scheduler="scheduler">
        <!-- 一秒一次 -->
        <task:scheduled ref="jobTest" method="jobPrint" cron="*/1 * * * * ?"/>
        <task:scheduled ref="jobTest" method="jobPrint2" cron="*/1 * * * * ?"/>
    </task:scheduled-tasks>
</beans>

这里因为我在applicationContext中import了这个文件,所以spring在加载的时候也会来解析这个文件,在spring-context中我发现了spring.handlers这个文件说明了那个类是用来解析schedule配置的

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.scheduling.config;

import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
import org.springframework.scheduling.config.AnnotationDrivenBeanDefinitionParser;
import org.springframework.scheduling.config.ExecutorBeanDefinitionParser;
import org.springframework.scheduling.config.ScheduledTasksBeanDefinitionParser;
import org.springframework.scheduling.config.SchedulerBeanDefinitionParser;

public class TaskNamespaceHandler extends NamespaceHandlerSupport {
    public TaskNamespaceHandler() {
    }

    public void init() {
        this.registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
        this.registerBeanDefinitionParser("executor", new ExecutorBeanDefinitionParser());
        this.registerBeanDefinitionParser("scheduled-tasks", new ScheduledTasksBeanDefinitionParser());
        this.registerBeanDefinitionParser("scheduler", new SchedulerBeanDefinitionParser());
    }
}

上面已经清楚的说到了每个xml属性配置是由哪个类来解析的。

spring加载的时候会实例化ContextLifecycleScheduledTaskRegistrar这个类,而这个类有继承了ScheduledTaskRegistrar类,ScheduledTaskRegistrar类就是整个spring配置里的定时任务的注册中心,
下面是这个类的几个成员属性。

public class ScheduledTaskRegistrar implements InitializingBean, DisposableBean {
    private TaskScheduler taskScheduler;
    private ScheduledExecutorService localExecutor;
    private List<TriggerTask> triggerTasks;
    private List<CronTask> cronTasks;
    private List<IntervalTask> fixedRateTasks;
    private List<IntervalTask> fixedDelayTasks;
    private final Set<ScheduledFuture<?>> scheduledFutures = new LinkedHashSet();

像开始的配置,最后加载到cronTasks这个属性里,至于是怎么存的,自己看一下源码就知道了。
接下来,spring就不停用线程来跑定时任务的方法了。

如果你想在代码运行的时候查看哪些你自己配置了哪些定时任务,很简单,加上这段代码

package com.galaxy.fym.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.config.ContextLifecycleScheduledTaskRegistrar;
import org.springframework.scheduling.config.CronTask;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Created by fengyiming on 2016/8/18.
 */
@Service
public class TaskService {
    private final Logger logger = LoggerFactory.getLogger("task service");

    @Autowired
    private ContextLifecycleScheduledTaskRegistrar contextLifecycleScheduledTaskRegistrar;

    public Object print(){
        try {
            //你所有配置的定时任务都在这个集合中
            List<CronTask> cronTasks = contextLifecycleScheduledTaskRegistrar.getCronTaskList();
            return cronTasks;
        }catch (Exception e){
            logger.error("------------------");
            return null;
        }
    }
}

无需再spring里实例化ContextLifecycleScheduledTaskRegistrar类,这个类已经被实例化好了。按需取值就行了。

目录
相关文章
|
10天前
|
Java 调度 Maven
Springboot实战篇--Springboot框架通过@Scheduled实现定时任务
Spring Boot的Scheduled定时任务无需额外Maven依赖,通过`@EnableScheduling`开启。任务调度有两种方式:fixedRate和fixedDelay,前者任务结束后立即按设定间隔执行,后者在任务完成后等待设定时间再执行。更灵活的是cron表达式,例如`0 0 3 * * ?`表示每天3点执行。实现定时任务时,需注意默认单线程执行可能导致的任务交错,可通过自定义线程池解决。
|
15天前
|
canal 缓存 关系型数据库
Spring Boot整合canal实现数据一致性解决方案解析-部署+实战
Spring Boot整合canal实现数据一致性解决方案解析-部署+实战
|
15天前
|
XML 人工智能 Java
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
|
28天前
|
XML Java 数据格式
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
24 0
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
|
28天前
|
前端开发 Java API
饼干探秘:深入Spring MVC中获取Cookie数据的技术解析
饼干探秘:深入Spring MVC中获取Cookie数据的技术解析
18 3
|
28天前
|
XML Java 数据格式
从入门到精通:Spring基础注解的全面解析
从入门到精通:Spring基础注解的全面解析
42 2
从入门到精通:Spring基础注解的全面解析
|
28天前
|
Java 数据库 Spring
切面编程的艺术:Spring动态代理解析与实战
切面编程的艺术:Spring动态代理解析与实战
29 0
切面编程的艺术:Spring动态代理解析与实战
|
3天前
|
Java Android开发
Android12 双击power键启动相机源码解析
Android12 双击power键启动相机源码解析
12 0
|
3天前
|
分布式计算 Java API
Java8 Lambda实现源码解析
Java8的lambda应该大家都比较熟悉了,本文主要从源码层面探讨一下lambda的设计和实现。
|
4天前
|
算法 Java Go
ArrayList源码解析
ArrayList源码解析
9 1

推荐镜像

更多