sequence
This article focuses on the ScheduledTasksEndpoint of springboot2
The instance
Annotation form
@Component
public class ScheduleTask {
@Scheduled(cron = "0, 0, 5 * *?)
public void cronJob(){
}
@Scheduled(fixedDelay = 2*60*1000,initialDelay = 30*1000)
public void fixedDelayJob(){
}
@Scheduled(fixedRate = 5 * 1000)
public void fixedRatejob() {}}Copy the code
Dynamically add
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addCronTask(new Runnable() {
@Override
public void run() {
System.out.println("hello"); }},"0 0 6 * *?"); }}Copy the code
/actuator/scheduledtasks
{
"cron": [{"runnable": {
"target": "com.example.task.ScheduleTask.cronJob"
},
"expression": "0, 0, 5 * *?
},
{
"runnable": {
"target": "com.example.config.ScheduleConfigThe $1"
},
"expression": "0 0 6 * *?"}]."fixedDelay": [{"runnable": {
"target": "com.example.task.ScheduleTask.fixedDelayJob"
},
"initialDelay": 30000,
"interval": 120000}]."fixedRate": [{"runnable": {
"target": "com.example.task.ScheduleTask.fixedRatejob"
},
"initialDelay": 0."interval": 5000}]}Copy the code
There are three types of cron expression type, fixedDelay type and fixedRate type.
The source code parsing
ScheduledTasksEndpointAutoConfiguration
Spring – the boot – physical – autoconfigure – 2.0.0. RELEASE – sources. The jar! /org/springframework/boot/actuate/autoconfigure/scheduling/ScheduledTasksEndpointAutoConfiguration.java
/**
* {@link EnableAutoConfiguration Auto-configuration} for {@link ScheduledTasksEndpoint}.
*
* @author Andy Wilkinson
* @since 2.0.0
*/
@Configuration
public class ScheduledTasksEndpointAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint
public ScheduledTasksEndpoint scheduledTasksEndpoint(
ObjectProvider<List<ScheduledTaskHolder>> holders) {
returnnew ScheduledTasksEndpoint(holders.getIfAvailable(Collections::emptyList)); }}Copy the code
Can see since 2.0 the config, here basically created a ScheduledTasksEndpoint, at the same time in the constructor to ObjectProvider < List < ScheduledTaskHolder > > holders
ScheduledTasksEndpoint
Spring – the boot – physical – 2.0.1. RELEASE – sources. The jar! /org/springframework/boot/actuate/scheduling/ScheduledTasksEndpoint.java
/**
* {@link Endpoint} to expose information about an application* * @author Andy Wilkinson * @since 2.0.0 */ @endpoint (id = "scheduledTasks ") public class ScheduledTasksEndpoint { private final Collection
scheduledTaskHolders; public ScheduledTasksEndpoint(Collection
scheduledTaskHolders) { this.scheduledTaskHolders = scheduledTaskHolders; } @ReadOperation public ScheduledTasksReport scheduledTasks() { Map
> descriptionsByType = this.scheduledTaskHolders .stream().flatMap((holder) -> holder.getScheduledTasks().stream()) .map(ScheduledTask::getTask).map(TaskDescription::of) .filter(Objects::nonNull) .collect(Collectors.groupingBy(TaskDescription::getType)); return new ScheduledTasksReport(descriptionsByType); } / /... }
,>
Copy the code
Here ScheduledTasksReport is created based on scheduledTaskHolders
ScheduledTasksReport
Spring – the boot – physical – 2.0.0. RELEASE – sources. The jar! /org/springframework/boot/actuate/scheduling/ScheduledTasksEndpoint.java
/**
* A report of an application's scheduled {@link Task Tasks}, primarily intended for * serialization to JSON. */ public static final class ScheduledTasksReport { private final List
cron; private final List
fixedDelay; private final List
fixedRate; private ScheduledTasksReport( Map
> descriptionsByType) { this.cron = descriptionsByType.getOrDefault(TaskType.CRON, Collections.emptyList()); this.fixedDelay = descriptionsByType.getOrDefault(TaskType.FIXED_DELAY, Collections.emptyList()); this.fixedRate = descriptionsByType.getOrDefault(TaskType.FIXED_RATE, Collections.emptyList()); } public List
getCron() { return this.cron; } public List
getFixedDelay() { return this.fixedDelay; } public List
getFixedRate() { return this.fixedRate; }}
,>
Copy the code
Here you can see that the report classifies scheduled tasks into cron, fixedDelay, and fixedRate.
SchedulingConfiguration
Spring – the context – 5.0.5. RELEASE – sources. The jar! /org/springframework/scheduling/annotation/SchedulingConfiguration.java
/**
* {@code @Configuration} class that registers a {@link ScheduledAnnotationBeanPostProcessor}
* bean capable of processing Spring's @{@link Scheduled} annotation. * * This configuration class is automatically imported when using the * {@link EnableScheduling @EnableScheduling} annotation. See * {@code @EnableScheduling}'
s javadoc forComplete Usage details. * * @author Chris Beams * @since 3.1 * @see EnableScheduling * @see ScheduledAnnotationBeanPostProcessor */ @Configuration @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public class SchedulingConfiguration { @Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public ScheduledAnnotationBeanPostProcessorscheduledAnnotationProcessor() {
returnnew ScheduledAnnotationBeanPostProcessor(); }}Copy the code
EnableScheduling will start this configuration, and then create ScheduledAnnotationBeanPostProcessor
ScheduledAnnotationBeanPostProcessor
Spring – the context – 5.0.5. RELEASE – sources. The jar! /org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java
/**
* Bean post-processor that registers methods annotated with @{@link Scheduled}
* to be invoked by a {@link org.springframework.scheduling.TaskScheduler} according
* to the "fixedRate"."fixedDelay", or "cron" expression provided via the annotation.
*
* <p>This post-processor is automatically registered by Spring's * {@code
} XML element, and also by the * {@link EnableScheduling @EnableScheduling} annotation. * *
Autodetects any {@link SchedulingConfigurer} instances in the container, * allowing for customization of the scheduler to be used or for fine-grained * control over task registration (e.g. registration of {@link Trigger} tasks. * See the @{@link EnableScheduling} javadocs for complete usage details. * * @author Mark Fisher * @author Juergen Hoeller * @author Chris Beams * @author Elizabeth Chatman * @since 3.0 * @see Scheduled * @see EnableScheduling * @see SchedulingConfigurer * @see org.springframework.scheduling.TaskScheduler * @see org.springframework.scheduling.config.ScheduledTaskRegistrar * @see AsyncAnnotationBeanPostProcessor */ public class ScheduledAnnotationBeanPostProcessor implements ScheduledTaskHolder, MergedBeanDefinitionPostProcessor, DestructionAwareBeanPostProcessor, Ordered, EmbeddedValueResolverAware, BeanNameAware, BeanFactoryAware, ApplicationContextAware, SmartInitializingSingleton, ApplicationListener
, DisposableBean { private final ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar(); private final Map
,>
" + beanName + "': " + annotatedMethods); } } } return bean; } @Override public void afterSingletonsInstantiated() { // Remove resolved singleton classes from cache this.nonAnnotatedClasses.clear(); if (this.applicationContext == null) { // Not running in an ApplicationContext -> register tasks early... finishRegistration(); } } @Override public void onApplicationEvent(ContextRefreshedEvent event) { if (event.getApplicationContext() == this.applicationContext) { // Running in an ApplicationContext -> register tasks this late... // giving other ContextRefreshedEvent listeners a chance to perform // their work at the same time (e.g. Spring Batch's job registration). finishRegistration(); }} / /... }Copy the code
-
GetScheduledTasks implements the ScheduledTaskHolder interface, which is used to obtain the registered ScheduledTask. It first adds the values of Map<Object, Set<ScheduledTask>> scheduledTasks, Then merge the registrar. GetScheduledTasks (). The main reason for the merger is that the ScheduledTaskRegistrar may use the system to dynamically add/update/override scheduled tasks at runtime
-
PostProcessAfterInitialization here to find out the ways to @ Scheduled, then call processScheduled to register
-
OnApplicationEvent and afterSingletonsInstantiated triggers finishRegistration, this method mainly from the realizing methods of SchedulingConfigurer interface in obtaining dynamic configuration task information regularly, The ScheduledTaskRegistrar is to transfer the new ScheduledTaskRegistrar to the interface of the SchedulingConfigurer implementation class. Then the scheduled task information will be integrated into the ScheduledTaskRegistrar.
processScheduled
protected void processScheduled(Scheduled scheduled, Method method, Object bean) { //... tasks.add(this.registrar.scheduleCronTask(new CronTask(runnable, new CronTrigger(cron, timeZone)))); / /... tasks.add(this.registrar.scheduleFixedDelayTask(new FixedDelayTask(runnable, fixedDelay, initialDelay))); / /... tasks.add(this.registrar.scheduleFixedRateTask(new FixedRateTask(runnable, fixedRate, initialDelay))); / /... synchronized (this.scheduledTasks) { Set<ScheduledTask> registeredTasks = this.scheduledTasks.get(bean);if(registeredTasks == null) { registeredTasks = new LinkedHashSet<>(4); this.scheduledTasks.put(bean, registeredTasks); } registeredTasks.addAll(tasks); }}Copy the code
Registrar registrar registrar registrar registrar registrar registrar registrar registrar registrar registrar registrar registrar registrar registrar registrar registrar registrar registrar registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registrar Registry Registry RegisteredTasks is the value of the map.
summary
Since springboot2.0, ScheduledTasksEndpoint is available in the actuator. By default, /actuator/scheduledtasks can access the information of scheduledtasks in the current application, which is very convenient.
doc
- spring-boot docs