|
|
// 定义包路径,用于存放任务调度配置类相关的代码。这个包名表明该类属于特定的项目模块(com.yf.exam)下的config部分,
|
|
|
// 通常用于组织和管理与任务调度配置相关的代码。
|
|
|
package com.yf.exam.config;
|
|
|
|
|
|
// 导入Lombok的Log4j2注解,用于简化日志记录的配置,通过该注解可以方便地在类中使用Log4j2进行日志输出。
|
|
|
import lombok.extern.log4j.Log4j2;
|
|
|
|
|
|
// 导入Spring框架中用于处理异步方法执行过程中未捕获异常的处理器接口。
|
|
|
// 当异步方法抛出异常且未在方法内部被捕获时,会由该处理器来处理异常情况,
|
|
|
// 在本类中实现该接口来定义异步未捕获异常的处理逻辑。
|
|
|
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
|
|
|
|
|
|
// 导入Spring框架中用于标记一个方法返回值为Spring Bean的注解。
|
|
|
// 被该注解标记的方法,其返回值会被Spring容器管理,作为一个可被注入到其他组件中的Bean实例。
|
|
|
// 在本类中用于将taskScheduler和asyncExecutor等方法返回的对象注册为Spring Bean。
|
|
|
import org.springframework.context.annotation.Bean;
|
|
|
|
|
|
// 导入Spring框架中用于标记一个类是配置类的注解。
|
|
|
// 被该注解标记的类可以在其中定义各种Bean配置方法,这些方法会被Spring容器在启动时自动识别并执行,
|
|
|
// 用于创建和配置应用程序所需的各种组件。在本类中用于标记该类为Spring配置类,以便进行任务调度相关的配置。
|
|
|
import org.springframework.context.annotation.Configuration;
|
|
|
|
|
|
// 导入Spring框架中用于配置异步任务执行相关设置的接口。
|
|
|
// 实现该接口可以定义异步任务执行的线程池等配置信息,在本类中实现该接口来配置异步任务执行的相关参数。
|
|
|
import org.springframework.scheduling.annotation.AsyncConfigurer;
|
|
|
|
|
|
// 导入Spring框架中用于启用异步任务执行功能的注解。
|
|
|
// 当在类上添加该注解后,Spring会自动识别并处理类中的异步方法,使其能够在独立的线程中执行。
|
|
|
// 在本类上添加该注解以启用异步任务执行功能。
|
|
|
import org.springframework.scheduling.annotation.EnableAsync;
|
|
|
|
|
|
// 导入Spring框架中用于启用任务调度功能的注解。
|
|
|
// 当在类上添加该注解后,Spring会自动识别并处理类中的定时任务等调度相关的设置,使其能够按照预定的时间执行任务。
|
|
|
// 在本类上添加该注解以启用任务调度功能。
|
|
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
|
|
|
|
|
// 导入Spring框架中用于配置任务调度相关设置的接口。
|
|
|
// 实现该接口可以定义任务调度的线程池、任务注册等配置信息,在本类中实现该接口来配置任务调度的相关参数。
|
|
|
import org.springframework.scheduling.annotation.SchedulingConfigurer;
|
|
|
|
|
|
// 导入Spring框架中用于执行线程池任务的执行器类。
|
|
|
// 它可以创建一个线程池,并通过该线程池来执行任务,在本类的asyncExecutor方法中用于创建异步任务执行的线程池。
|
|
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
|
|
|
|
|
// 导入Spring框架中用于调度线程池任务的调度器类。
|
|
|
// 它可以创建一个线程池,并通过该线程池来调度任务的执行时间,在本类的taskScheduler方法中用于创建定时任务执行的线程池。
|
|
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
|
|
|
|
|
// 导入Spring框架中用于注册调度任务的类。
|
|
|
// 通过它可以将需要调度执行的任务注册到相应的调度器中,在本类的configureTasks方法中用于设置任务调度器。
|
|
|
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
|
|
|
|
|
// 导入Java标准库中的执行器接口,它定义了执行任务的通用规范,
|
|
|
// 在本类的getAsyncExecutor方法中用于返回异步任务执行的执行器对象。
|
|
|
import java.util.concurrent.Executor;
|
|
|
|
|
|
// 导入Java标准库中的线程池执行器类,它是实现了线程池功能的具体类,
|
|
|
// 在本类的asyncExecutor方法中用于设置异步任务执行线程池的拒绝策略。
|
|
|
import java.util.concurrent.ThreadPoolExecutor;
|
|
|
|
|
|
/**
|
|
|
* 任务调度配置类,主要功能是配置任务调度和异步任务执行相关的设置,
|
|
|
* 包括创建定时任务执行的线程池和异步任务执行的线程池,设置线程池的大小、名称前缀、
|
|
|
* 等待终止时间、队列容量等参数,同时实现了处理异步未捕获异常的逻辑。
|
|
|
* @author bool
|
|
|
*/
|
|
|
@Log4j2 // 使用Log4j2注解启用日志记录功能,方便在类中记录相关操作的日志信息。
|
|
|
@Configuration // 使用该注解标记此为Spring配置类,表明这个类是用来进行Spring应用程序的配置工作的。
|
|
|
@EnableScheduling // 使用该注解启用任务调度功能,使得Spring能够识别并处理类中的定时任务等调度相关设置。
|
|
|
@EnableAsync // 使用该注解启用异步任务执行功能,使得Spring能够识别并处理类中的异步方法,使其能够在独立的线程中执行。
|
|
|
public class ScheduledConfig implements SchedulingConfigurer, AsyncConfigurer {
|
|
|
|
|
|
/**
|
|
|
* 定义一个方法,并使用@Bean注解将其返回值声明为Spring Bean。
|
|
|
* 该方法用于创建并返回一个线程池任务调度器(ThreadPoolTaskScheduler)对象,用于定时任务的执行调度。
|
|
|
*
|
|
|
* @return 返回一个线程池任务调度器(ThreadPoolTaskScheduler)对象,该对象已进行了相关设置(如线程池大小、名称前缀等)。
|
|
|
*/
|
|
|
@Bean(destroyMethod = "shutdown", name = "taskScheduler") // 将该方法返回的线程池任务调度器对象声明为Spring Bean,
|
|
|
// 并指定销毁方法为"shutdown",以便在容器关闭时正确关闭线程池。
|
|
|
public ThreadPoolTaskScheduler taskScheduler() {
|
|
|
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); // 创建一个新的线程池任务调度器对象。
|
|
|
|
|
|
// 设置线程池的大小,即同时可执行的定时任务数量,这里设置为10,表示线程池最多可同时执行10个定时任务。
|
|
|
scheduler.setPoolSize(10);
|
|
|
|
|
|
// 设置线程的名称前缀,用于在日志等场景中方便识别线程所属的任务调度器,这里设置为"task-",
|
|
|
// 生成的线程名称可能类似"task-1"、"task-2"等。
|
|
|
scheduler.setThreadNamePrefix("task-");
|
|
|
|
|
|
// 设置线程池在关闭时等待任务完成的时间,单位为秒,这里设置为600秒(10分钟),
|
|
|
// 表示在容器关闭时,线程池会等待正在执行的任务完成,最长等待时间为10分钟。
|
|
|
scheduler.setAwaitTerminationSeconds(600);
|
|
|
|
|
|
// 设置在关闭时是否等待任务完成,这里设置为true,表示在容器关闭时,线程池会等待所有任务完成后再关闭。
|
|
|
scheduler.setWaitForTasksToCompleteOnShutdown(true);
|
|
|
|
|
|
// 返回设置好的线程池任务调度器对象,该对象将被Spring容器管理并在定时任务执行场景中被调用进行任务调度。
|
|
|
return scheduler;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 定义一个方法,并使用@Bean注解将其返回值声明为Spring Bean。
|
|
|
* 该方法用于创建并返回一个线程池任务执行器(ThreadPoolTaskExecutor)对象,用于异步任务的执行。
|
|
|
*
|
|
|
* @return 返回一个线程池任务执行器(ThreadPoolTaskExecutor)对象,该对象已进行了相关设置(如核心线程数、队列容量等)。
|
|
|
*/
|
|
|
@Bean(name = "asyncExecutor") // 将该方法返回的线程池任务执行器对象声明为Spring Bean,以便Spring容器能够管理和注入到其他需要使用的地方。
|
|
|
public ThreadPoolTaskExecutor asyncExecutor() {
|
|
|
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 创建一个新的线程池任务执行器对象。
|
|
|
|
|
|
// 设置线程池的核心线程数,即线程池始终保持的活跃线程数量,这里设置为10,表示线程池至少会保持10个线程处于活跃状态。
|
|
|
executor.setCorePoolSize(10);
|
|
|
|
|
|
// 设置线程池的队列容量,即用于存储等待执行任务的队列大小,这里设置为1000,表示队列最多可容纳1000个等待执行的任务。
|
|
|
executor.setQueueCapacity(1000);
|
|
|
|
|
|
// 设置线程池中非核心线程的保持活动时间,单位为秒,这里设置为600秒(10分钟),
|
|
|
// 表示当非核心线程空闲时间超过10分钟时,可能会被回收。
|
|
|
executor.setKeepAliveSeconds(600);
|
|
|
|
|
|
// 设置线程池的最大线程数,即线程池最多可同时拥有的线程数量,这里设置为20,表示线程池最多可扩展到20个线程同时执行任务。
|
|
|
executor.setMaxPoolSize(20);
|
|
|
|
|
|
// 设置线程的名称前缀,用于在日志等场景中方便识别线程所属的任务执行器,这里设置为"taskExecutor-",
|
|
|
// 生成的线程名称可能类似"taskExecutor-1"、"taskExecutor-2"等。
|
|
|
executor.setThreadNamePrefix("taskExecutor-");
|
|
|
|
|
|
// 设置线程池的拒绝策略,这里采用ThreadPoolExecutor.CallerRunsPolicy(),
|
|
|
// 表示当线程池和队列都已满,无法再接受新任务时,会由调用线程来执行该任务,而不是直接抛出异常。
|
|
|
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
|
|
|
|
|
// 初始化线程池,使其处于可使用状态,完成各项参数的设置和内部资源的初始化。
|
|
|
executor.initialize();
|
|
|
|
|
|
// 返回设置好的线程池任务执行器对象,该对象将被Spring容器管理并在异步任务执行场景中被调用进行任务执行。
|
|
|
return executor;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 实现SchedulingConfigurer接口的方法,用于配置任务调度相关的设置。
|
|
|
* 在本方法中,获取之前创建的线程池任务调度器对象,并将其设置到调度任务注册类中,
|
|
|
* 以便后续注册的定时任务能够使用该调度器进行任务调度。
|
|
|
*
|
|
|
* @param scheduledTaskRegistrar 调度任务注册类对象,用于注册调度任务和设置调度器等操作。
|
|
|
*/
|
|
|
@Override
|
|
|
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
|
|
|
ThreadPoolTaskScheduler taskScheduler = taskScheduler(); // 获取之前创建的线程池任务调度器对象。
|
|
|
|
|
|
// 将获取到的线程池任务调度器对象设置到调度任务注册类中,使得后续注册的定时任务能够使用该调度器进行任务调度。
|
|
|
scheduledTaskRegistrar.setTaskScheduler(taskScheduler);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 实现AsyncConfigurer接口的方法,用于返回异步任务执行的执行器对象。
|
|
|
* 在本方法中,直接返回之前创建的线程池任务执行器对象,该对象将作为异步任务执行的执行器。
|
|
|
*
|
|
|
* @return 返回异步任务执行的执行器对象,即之前创建的线程池任务执行器对象。
|
|
|
*/
|
|
|
@Override
|
|
|
public Executor getAsyncExecutor() {
|
|
|
return asyncExecutor();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 实现AsyncConfigurer接口的方法,用于定义异步未捕获异常的处理逻辑。
|
|
|
* 在本方法中,当异步任务执行出现异常且未在方法内部被捕获时,会通过日志记录异常信息,
|
|
|
* 包括异常对象、执行的方法以及方法的参数等内容。
|
|
|
*
|
|
|
* @param throwable 异步任务执行过程中抛出的异常对象。
|
|
|
* @param method 执行异步任务的方法对象。
|
|
|
* @param objects 执行异步任务的方法的参数对象数组。
|
|
|
* @return 返回值无实际意义,这里主要是为了符合AsyncUncaughtExceptionHandler接口的定义。
|
|
|
*/
|
|
|
@Override
|
|
|
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
|
|
|
return (throwable, method, objects) -> {
|
|
|
log.error("异步任务执行出现异常, message {}, method {}, params {}", throwable, method, objects);
|
|
|
};
|
|
|
}
|
|
|
} |