Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the principle of @ Schedule in SpringBoot

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

Today, I will talk to you about the principle of @ Schedule in SpringBoot, which may not be well understood by many people. in order to make you understand better, the editor has summarized the following content for you. I hope you can get something according to this article.

Note @ Schedule default thread pool size

I believe that the default thread pool size of @ Schedule is ignored by many friends who use it. By default, @ Schedule uses a thread pool size of 1.

In general, there is no problem, but if there are multiple scheduled tasks, and the execution time of each scheduled task may not be short, then some scheduled tasks may not have the opportunity to be executed all the time.

If you are interested, you can try:

@ Componentpublic class BrigeTask {private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern ("yyyy-MM-dd HH:mm:ss"); @ Scheduled (cron = "* / 5 *?") Private void cron () throws InterruptedException {System.out.println (Thread.currentThread (). GetName () + "- cron:" + LocalDateTime.now () .format (FORMATTER)); TimeUnit.SECONDS.sleep (6);} @ Scheduled (fixedDelay = 5000) private void fixedDelay () throws InterruptedException {System.out.println (Thread.currentThread (). GetName () + "- fixedDelay:" + LocalDateTime.now () .format (FORMATTER); TimeUnit.SECONDS.sleep (6) } @ Scheduled (fixedRate = 5000) private void fixedRate () throws InterruptedException {System.out.println (Thread.currentThread () .getName () + "- fixedRate:" + LocalDateTime.now () .format (FORMATTER)); TimeUnit.SECONDS.sleep (6);}}

The above tasks, fixedDelay and cron, may not be performed for a long time.

To solve the above problem, you can set a larger thread pool to execute the task, and how to configure it in the configureTasks method by implementing the SchedulingConfigurer interface. See the following code, where you can directly inject a TaskScheduler to solve the problem.

@ Beanpublic TaskScheduler taskScheduler () {ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler (); taskScheduler.setPoolSize (5); return taskScheduler;}

Of course, you can use ScheduledExecutorService:

@ Beanpublic ScheduledExecutorService scheduledExecutorService () {return Executors.newScheduledThreadPool (10);}

Why this works, please refer to the following @ Schedule principle.

Fixed delay and fixed rate

The three ways of @ Schedule cron, fixedDelay, and fixedRate, regardless of whether the thread is enough or not, will block until the last execution is completed before the next execution.

If the execution time of the task method is very short, there is not much difference between the above three methods.

If the execution time of the task method is longer than the set execution cycle, then there is a big difference. For example, assuming that there are enough threads to execute the task, the execution cycle is 5s, and the task method executes for 6s.

The execution mode of cron is that when the task method is executed, the next match will be executed again in 10 seconds, because the time interval for executing the task method will miss a match.

The way fixedDelay executes is that the method executes for 6 seconds, and then waits for 5 seconds to execute the next time, basically every 11 seconds under the above conditions.

The execution mode of fixedRate is every 6s, because it should be executed in less than 5s according to a fixed interval, but the task method has been executed for 6s, so it has to be executed once in 6s.

The above conclusions can be passed, and the above example verifies that interested friends can adjust the dormancy time to test it.

SpringBoot @ Schedule principle

In SpringBoot, we use @ EnableScheduling to enable @ Schedule.

@ Target (ElementType.TYPE) @ Retention (RetentionPolicy.RUNTIME) @ Import (SchedulingConfiguration.class) @ Documentedpublic @ interface EnableScheduling {}

There is nothing special about EnableScheduling annotations, so you need to pay attention to import SchedulingConfiguration.

SchedulingConfiguration can tell at a glance that it is a configuration class, and it must be to add the corresponding dependent class.

@ Configuration@Role (BeanDefinition.ROLE_INFRASTRUCTURE) public class SchedulingConfiguration {@ Bean (name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME) @ Role (BeanDefinition.ROLE_INFRASTRUCTURE) public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor () {return new ScheduledAnnotationBeanPostProcessor ()

We can see that a ScheduledAnnotationBeanPostProcessor is created in SchedulingConfiguration.

It seems that the core of SpringBoot scheduled tasks is the ScheduledAnnotationBeanPostProcessor class, so let's take a look at the ScheduledAnnotationBeanPostProcessor class.

ScheduledAnnotationBeanPostProcessorpublic class ScheduledAnnotationBeanPostProcessor implements ScheduledTaskHolder, MergedBeanDefinitionPostProcessor, DestructionAwareBeanPostProcessor, Ordered, EmbeddedValueResolverAware, BeanNameAware, BeanFactoryAware, ApplicationContextAware, SmartInitializingSingleton, ApplicationListener, DisposableBean {}

ScheduledAnnotationBeanPostProcessor implements a lot of interfaces, and here we focus on two, ApplicationListener and DestructionAwareBeanPostProcessor.

DestructionAwareBeanPostProcessor encapsulation task

DestructionAwareBeanPostProcessor inherits BeanPostProcessor.

BeanPostProcessor is already familiar to you. After Bean creates and executes setter, it provides intercept points before and after custom afterPropertiesSet and init-method. The sequence of execution is roughly as follows:

Bean instantiation-> setter-> BeanPostProcessor#postProcessBeforeInitialization->

-> InitializingBean#afterPropertiesSet-> init-method-> BeanPostProcessor#postProcessAfterInitialization

Let's take a look at ScheduledAnnotationBeanPostProcessor's postProcessAfterInitialization method:

Overridepublic Object postProcessAfterInitialization (Object bean, String beanName) {if (bean instanceof AopInfrastructureBean | | bean instanceof TaskScheduler | | bean instanceof ScheduledExecutorService) {/ / Ignore AOP infrastructure such as scoped proxies. Return bean;} Class targetClass = AopProxyUtils.ultimateTargetClass (bean) If (! this.nonAnnotatedClasses.contains (targetClass) & & AnnotationUtils.isCandidateClass (targetClass, Arrays.asList (Scheduled.class, Schedules.class)) {Map annotatedMethods = MethodIntrospector.selectMethods (targetClass, (MethodIntrospector.MetadataLookup) method-> {Set scheduledMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations (method, Scheduled.class, Schedules.class) Return (! scheduledMethods.isEmpty ()? ScheduledMethods: null);}); if (annotatedMethods.isEmpty ()) {this.nonAnnotatedClasses.add (targetClass); if (logger.isTraceEnabled ()) {logger.trace ("No @ Scheduled annotations found on bean class:" + targetClass) }} else {/ / Non-empty set of methods annotatedMethods.forEach ((method, scheduledMethods)-> scheduledMethods.forEach (scheduled-> processScheduled (scheduled, method, bean)) If (logger.isTraceEnabled ()) {logger.trace (annotatedMethods.size () + "@ Scheduled methods processed on bean'" + beanName + "':" + annotatedMethods);} return bean;}

A brief description of the process:

Find all the Schedule methods, wrap it as a ScheduledMethodRunnable class (the ScheduledMethodRunnable class implements the Runnable interface), and register it as a task in ScheduledTaskRegistrar.

If you are interested in specific logic, you can debug along the processScheduled method from the postProcessAfterInitialization method.

ApplicationListener executes the task

We described earlier that all the tasks have been parsed through BeanPostProcessor, and the next thing to do is to submit the task.

@ Overridepublic 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 ();}}

The event that ScheduledAnnotationBeanPostProcessor listens for is ContextRefreshedEvent, which is called when the container is initialized or refreshed.

After listening for the ContextRefreshedEvent event, the value calls the finishRegistration method. The basic flow of this method is as follows:

The main purpose of finding the SchedulingConfigurer in the container and calling its configureTasks,SchedulingConfigurer is to configure the ScheduledTaskRegistrar class, such as parameters such as thread pool, for example:

Import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.SchedulingConfigurer;import org.springframework.scheduling.config.ScheduledTaskRegistrar;import java.util.concurrent.Executors;@Configurationpublic class MyScheduleConfig implements SchedulingConfigurer {@ Override public void configureTasks (ScheduledTaskRegistrar taskRegistrar) {taskRegistrar.setScheduler (Executors.newScheduledThreadPool (10));}}

Call the afterPropertiesSet method of ScheduledTaskRegistrar to perform the task. If you are interested in the specific logic, you can read the scheduleTasks method of ScheduledTaskRegistrar.

After reading the above, do you have any further understanding of the principle of @ Schedule in SpringBoot? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report