1.通过在启动类上+@EnableScheduling注解
//标记启动类
@SpringBootApplication (scanBasePackages = OpenPowerConstants.BASE_SCAN_PACKAGE)
//启用服务发现客户端功能
@EnableDiscoveryClient
//这个注解用于启用 Feign 客户端功能,参数指定了需要扫描的 Feign 客户端接口所在的包路径
@EnableFeignClients (basePackages = OpenPowerConstants.BASE_SCAN_PACKAGE)
//扫描mapper
@MapperScan (OpenPowerConstants.MAPPER_SCAN_PACKAGE)
//这个注解用于启用 Spring 的缓存支持,可以通过在方法上标注 @Cacheable、@CachePut、@CacheEvict 等注解来实现缓存功能。
@EnableCaching
//这个注解用于启用 Spring 的异步方法调用支持,可以通过在方法上标注 @Async 注解来实现方法的异步执行。
@EnableAsync
//开启定时任务
@EnableScheduling
public class OpenPowerApi
{
public static void main (String[] args)
{
SpringApplication.run (OpenPowerApi.class, args);
}
}
2.创建一个类,将需要定时的动作写成方法在方法上+@Scheduled注解
@Component
@RequiredArgsConstructor
@Slf4j
public class AppConfigPublisher {
@Scheduled(cron = "0 0 0/1 * * ?")
public void publishConfig() {
try {
// 查询动作
List<AppPowerResp> appPowerList = appPowerService.allRelation();
} catch (NacosException e) {
log.error ("task NacosException", e);
}
}
但是这种方法是单线程,会出现阻塞情况,所以我们使用多线程异步来优化
1.创建一个默认异步任务线程池配置类
import com.huawei.cloud.phone.provider.psbo.config.AsyncTaskPoolConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
Slf4j
@Configuration
public class AsyncTaskExecutorConfig implements AsyncConfigurer
{
private final AsyncTaskPoolConfig config;
public AsyncTaskExecutorConfig (AsyncTaskPoolConfig config)
{
this.config = config;
}
@Override
@Bean("myAsync")
public Executor getAsyncExecutor ()
{
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor ();
// 核心线程池大小
executor.setCorePoolSize (config.getCorePoolSize ());
// 最大线程数
executor.setMaxPoolSize (config.getMaxPoolSize ());
// 队列容量
executor.setQueueCapacity (config.getQueueCapacity ());
// 活跃时间
executor.setKeepAliveSeconds (config.getKeepAliveSeconds ());
// 线程名字前缀
executor.setThreadNamePrefix (config.getThreadNamePrefix ());
// 异步mdc
executor.setTaskDecorator (new MdcTaskDecorator ());
// setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务
// CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
executor.setRejectedExecutionHandler (new ThreadPoolExecutor.CallerRunsPolicy ());
executor.initialize ();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler ()
{
return (throwable, method, objects) -> {
log.error ("====" + throwable.getMessage () + "====", throwable);
log.error ("exception method:" + method.getName ());
};
}
}
2.在方法中去匹配这个bean
@Component
@RequiredArgsConstructor
@Slf4j
public class AppConfigPublisher {
@Scheduled(cron = "0 0 0/1 * * ?")
@Async("myAsync")
public void publishConfig() {
try {
// 查询动作
List<AppPowerResp> appPowerList = appPowerService.allRelation();
} catch (NacosException e) {
log.error ("task NacosException", e);
}
}
2.启动类使用+@EnableAsync注解
@SpringBootApplication (scanBasePackages = OpenPowerConstants.BASE_SCAN_PACKAGE)
@EnableDiscoveryClient
@EnableFeignClients (basePackages = OpenPowerConstants.BASE_SCAN_PACKAGE)
@MapperScan (OpenPowerConstants.MAPPER_SCAN_PACKAGE)
@EnableCaching
@EnableAsync
@EnableScheduling
public class OpenPowerApi
{
public static void main (String[] args)
{
SpringApplication.run (OpenPowerApi.class, args);
}
}