spring @Scheduled定时任务使用说明及基本工作原理介绍

使用说明及工作原理:

package com.example.spring.async;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import com.example.spring.MyLog;
/**
 * 定时任务使用示例
 *  1.启动类增加注解 @EnableScheduling
 *  2.相应类声明为服务 @Service
 *  3.方法上面增加 @Scheduled, 指定不同的参数以不同的方式运行定时任务
 * 备注:
 *  @Scheduled中参数解释:
 *      fixedRate:表示以固定的时间间隔执行(上次开始执行和本次开始执行之间的时间间隔),不关注被执行方法实际的执行时间
 *      fixedDelay:表示以固定的延迟执行(上次执行结束和本次开始执行的时间间隔),受被执行方法执行时间的影响
 *      cron="2 * * * * *": cron表达式配置执行方法。总共6位,分别代表 秒 分 时 日 月 周
 *  spring底层执行器:(默认使用的是单线程线程池)
 *      this.localExecutor = Executors.newSingleThreadScheduledExecutor();
 *      this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
 *  加载流程:
 *      ScheduledAnnotationBeanPostProcessor -> ScheduledTaskRegistrar -> afterPropertiesSet()
 *  @Scheduled 的方法必须是空返回值和无参方法,直接调用这个方法是同步的
 * @DESC 
 * @author guchuang
 *
 */
@Service
public class ScheduleMethod {
    
    public ScheduleMethod() {
        MyLog.info("-----------------------ScheduleMethod init--------------------------");
    }
    /*@Scheduled(fixedRate=2000)
    public void foo1() {
        MyLog.info("每2秒执行一次,不管上次执行完成时间,fixedRate=2000");
    }
    
    @Scheduled(fixedDelay=2000)
    public void foo2() {
        MyLog.info("上次执行完成,2s后执行,以此递推,fixedDelay=2000");
    }*/
    
    @Scheduled(fixedRate=2000)
    public void foo3() {
        MyLog.info("每2秒执行一次,不管上次执行完成时间,fixedRate=2000");
        MyLog.sleep(1000);
    }
    
    /*@Scheduled(fixedDelay=10000)
    public void foo4() {
        //MyLog.info("上次执行完成,2s后执行,以此递推,fixedDelay=3000");
        MyLog.info("上次执行完成,2s后执行,以此递推,fixedDelay=3000 ----start");
        MyLog.sleep(1000);
        MyLog.info("上次执行完成,2s后执行,以此递推,fixedDelay=3000 ----end");
    }*/
    
    @Scheduled(cron="*/2 * * * * *")
    public void foo5() {
        MyLog.info("cron test--每隔两秒执行一次");
    }
}

配置类:

package com.example.spring.async.config;

import java.util.concurrent.Executors;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import com.example.spring.MyThreadFactory;

@Configuration
public class ScheduleConfig implements SchedulingConfigurer{
    
    /**
     * 向spring容器注入TaskScheduler线程池,用于执行@Scheduled注解标注的方法.
     * 类型为TaskScheduler.class, name为taskExecutor1的bean(使用类型注入spring,不是bean name)
     * 如果没有注入TaskScheduler或者ScheduledExecutorService,则默认使用单线程的线程池作为底层支撑
     * @return TaskScheduler 实例
     */
    @Bean
    public TaskScheduler taskExecutor() {
        return new ConcurrentTaskScheduler(Executors.newScheduledThreadPool(3, new MyThreadFactory("scheduled")));
    }
    
    @Bean
    @Qualifier("test-123")
    public TaskScheduler taskExecutor2() {
        return new ConcurrentTaskScheduler(Executors.newScheduledThreadPool(3, new MyThreadFactory("scheduled2")));
    }

    /**
     * 可以用于执行定时任务,设置taskScheduler等
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        //taskRegistrar.setScheduler(taskExecutor1());      用于显示的设置线程池执行器
        taskRegistrar.addFixedDelayTask(() -> System.out.println("SchedulingConfigurer test"), 5000);
    }
    
}

测试类

package com.example.spring.async;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import com.example.spring.BaseDemoApplicationTest;
import com.example.spring.MyLog;
import com.example.spring.async.ScheduleMethod;

public class ScheduleMethodTest extends BaseDemoApplicationTest {

    @Autowired
    ScheduleMethod schedule;
    
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
    }

    @Before
    public void setUp() throws Exception {
    }

    @Test
    public void test() {
        MyLog.sleep(1000 * 30);
    }

}

猜你喜欢

转载自www.cnblogs.com/gc65/p/11183843.html