spring定时任务在boot中的使用

1.对于定时任务的配置,还是建议配置线程池使用,较好,也可以设置异步线程池;2.定时任务spring提供了SchedulingConfigurer类,并实现里面的方法,看了看源码,它是把每个跑任务的定义为一个类下的一个方法,且也是new出来一个Runnable匿名内部类放进线程池中的。对于Task类是自己定义的,参数 可以按照自己的意愿进行添加修改。

本节代码大致思路,数据库定义一个定时任务表,包含类和方法和cron,然后获取到active=y的任务根据cron来跑。

暂时只是浅浅的研究到这个地步,具体去spring官网:https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#scheduling

package com.linkcheers.task.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;


/**
 * 定时任务配置
 */
@Configuration
@EnableAsync
@EnableScheduling
public class DynamicTask implements SchedulingConfigurer, AsyncConfigurer{

	private final static Logger LOGGER = LoggerFactory.getLogger(DynamicTask.class);

	@Bean(destroyMethod = "shutdown", name = "taskScheduler")
	public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
		ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
		threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true);
		threadPoolTaskScheduler.setAwaitTerminationSeconds(60);
		threadPoolTaskScheduler.setPoolSize(8);
		threadPoolTaskScheduler.setThreadNamePrefix("assign-taskScheduled-");
		//务必调用此方法来启动
		threadPoolTaskScheduler.initialize();
		return threadPoolTaskScheduler;
	}

	/**
	 * 异步任务执行线程池
	 * @return
	 */
	@Bean(destroyMethod = "shutdown",name = "asyncExecutor")
	public ThreadPoolTaskExecutor asyncExecutor() {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		executor.setCorePoolSize(10);
		executor.setQueueCapacity(1000);
		executor.setKeepAliveSeconds(600);
		executor.setMaxPoolSize(20);
		executor.setThreadNamePrefix("assign-async-taskExecutor-");
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		executor.initialize();
		return executor;
	}

	@Override
	public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
		ThreadPoolTaskScheduler taskScheduler = threadPoolTaskScheduler();
		scheduledTaskRegistrar.setTaskScheduler(taskScheduler);
	}

	@Override
	public Executor getAsyncExecutor() {
		return asyncExecutor();
	}

	@Override
	public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
		return (throwable, method, objects) -> {
			LOGGER.error("异步任务执行出现异常, message {}, emthod {}, params {}", throwable, method, objects);
		};
	}
}
package com.linkcheers.task;

import com.linkcheers.config.ApplicationContextHelper;
import com.linkcheers.task.model.TbScheduleTask;
import com.linkcheers.task.service.TbScheduleTaskService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ScheduledFuture;

@Component
public class TaskSchedule implements SchedulingConfigurer{

    private static final Logger LOGGER = LoggerFactory.getLogger(TaskSchedule.class);

    @Autowired
    @Qualifier("taskScheduler")
    private ThreadPoolTaskScheduler threadPoolTaskScheduler;

    @Autowired
    private TbScheduleTaskService taskService;


    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        List<TbScheduleTask> list = taskService.activeList();
        if(list!=null && list.size()>0){
            LOGGER.info("本次启动定时任务"+list.size()+"个........");
            list.forEach(s -> {
                // schedule方法,周期性执行;execute 执行一次
                ScheduledFuture<?> future = threadPoolTaskScheduler.schedule(getTask(s), getTrigger(s));
            });
        }
    }


    /**
     * Trigger
     *
     * @param task 任务
     * @return Trigger Trigger
     */
    private Trigger getTrigger(TbScheduleTask task) {
        return new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                CronTrigger trigger = new CronTrigger(task.getCron());
                Date nextExec = trigger.nextExecutionTime(triggerContext);
                return nextExec;
            }
        };
    }

    /**
     * runnable
     *
     * @param task 任务
     * @return Runnable
     */
    private Runnable getTask(TbScheduleTask task) {
        return new Runnable() {
            @Override
            public void run() {
                Class<?> clazz;
                try {
                    clazz = Class.forName(task.getClassName());
                    String className = lowerFirstCapse(clazz.getSimpleName());
                    Object bean = ApplicationContextHelper.getBean(className);
                    Method method = ReflectionUtils.findMethod(bean.getClass(), task.getMethod());
                    if ("Y".equals(task.getAsync())) {
                        synchronized (this) {
                            ReflectionUtils.invokeMethod(method, bean);
                        }
                    } else {
                        ReflectionUtils.invokeMethod(method,bean);
                    }
                } catch (Exception e) {
                    LOGGER.error("定时任务报错@Exception",e);
                }
            }
        };
    }

    /**
     * 转换首字母小写
     *
     * @param str
     * @return
     */
    public static String lowerFirstCapse(String str) {
        char[] chars = str.toCharArray();
        chars[0] += 32;
        return String.valueOf(chars);
    }


}
package com.linkcheers.task.model;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tb_schedule_task")
public class TbScheduleTask {

    @TableId(type = IdType.AUTO)
    private Integer id;

    @TableField("class_name")
    private String className;

    private String method;

    private String cron;

    //是否线程安全
    private String async;

    private String active;

    private String desc;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值