SpringBoot定时任务@Scheduled注解

Spring中的@Scheduled可以进行定时任务开发,定时执行方法。

1、先在yml中配置定时任务的开关,false默认是关闭,true是开启

subway:
 # 定时任务开关
 EnvironmentalAlarmTask: false

2、新建一个执行类,并在执行类上加注解@EnableScheduling,在类里面的实现方法上加注解@Scheduled

import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
@EnableScheduling
public class EnvironmentalAlarmTask {

	/**
     * 任务开关
     */
    @Value("${subway.EnvironmentalAlarmTask:false}")
    private boolean taskOnOff;

	/**
     * 定时更新环境监测报警信息
     * 每一分钟执行一次
     */
    @Scheduled(cron = "0 0/1 * * * ?")
    public void task() throws InterruptedException {
    	// 如果没有加下文步骤4的定时任务控制类,需用此条件执行
		if(!taskOnOff) {
            return;
        }
        
        // 如果加了下文步骤4的定时任务控制类,需用此条件执行,并注释掉前一个if条件
		// if(!taskOnOff || !MySignalHandler.BASE_FLAG) {
		// 		return;
		// }
        
        TaskEnum.AddEnvironmentalTask.start();   // 定时任务开始执行
        
		try {
			//TODO  此处可写业务逻辑
            System.out.println("999999");
            
		}catch (Exception e){
            e.printStackTrace();
        }finally {
            TaskEnum.AddEnvironmentalTask.end();    // 定时任务停止执行
        }
    }
}

3、新建一个枚举类,来控制定时任务的开始和停止

import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.atomic.AtomicBoolean;

@Slf4j
public enum TaskEnum {

	AddEnvironmentalTask("更新环境监测数据中的设备信息", new AtomicBoolean(false)),

	private String name;
    private AtomicBoolean running;

	TaskEnum(String name, AtomicBoolean running){
        this.name = name;
        this.running = running;
    }

	public void start(){
        running.set(true);
    }

    public void end(){
        running.set(false);
    }
    
	public static boolean allStop(){
        for(TaskEnum task:TaskEnum.values()){
            if(task.running.get()){
                log.info("等待 {} 执行完毕", task.name);
                return false;
            }
        }
        return true;
    }
}

4、再写一个定时任务控制类,来实现定时任务安全退出(此控制类不写,也能实现正常的定时执行任务的功能,但是为了系统安全,最好加上此控制类)

import org.slf4j.LoggerFactory;
import sun.misc.Signal;
import sun.misc.SignalHandler;

/**
 * @description: 定时任务控制类(实现安全退出)
 */
public class MySignalHandler implements SignalHandler {

	private final static org.slf4j.Logger logger = LoggerFactory.getLogger(MySignalHandler.class);

    private SignalHandler oldHandler;
     /**
     * 定时任务总开关-状态:true:打开 false:关闭
     */
    protected static boolean BASE_FLAG = true;

	@Override
    public void handle(Signal signal) {
        signalAction(signal);
    }
	
	public static SignalHandler install(String signalName) {
        Signal diagSignal = new Signal(signalName);
        MySignalHandler instance = new MySignalHandler();
        instance.oldHandler = Signal.handle(diagSignal, instance);
        return instance;
    }

	public void signalAction(Signal signal) {
        try {

            BASE_FLAG = false;
            logger.info("\n执行安全退出操作\n等待运行中任务执行完毕…………");
            Thread.sleep(1000);
            while (!TaskEnum.allStop()){
                //等待线程任务执行完毕
                Thread.sleep(1000);
            }
            //获取到的上下文对象关闭相应的程序。
            //(注:SubwayDeviceApplication是我自己项目的启动类,实际应用中需将其替换成你们自己项目的启动类)
            SubwayDeviceApplication.context.close();
            logger.info("\n================\n程序已安全退出!\n================");
            oldHandler.handle(signal);
        } catch (Exception e) {
            logger.error("handle|Signal handler" + "failed, reason "
                    + e.getMessage());
            e.printStackTrace();
        }
    }
}

最后把yml配置文件中的false改成true,然后再启动项目,就成功开启定时任务了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值