@Scheduled 和@Async 在 spring-boot 中共享同一个线程池

@Scheduled and @Async are sharing same threadpool in spring-boot

我配置了两个不同的线程池,一个用于 @Scheduled,另一个用于 @Async。但是,我注意到 @Async 的线程池没有被使用。

这是调度程序配置

@Configuration
@EnableScheduling
public class SchedulerConfig implements SchedulingConfigurer {
    private final int POOL_SIZE = 10;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
        threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
        threadPoolTaskScheduler.setThreadNamePrefix("my-sched-pool-");
        threadPoolTaskScheduler.initialize();
        scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
    }
}

这是异步的配置

@Configuration
@EnableAsync
public class AppConfig {

 @Bean(name = "asyncTaskExecutor")
    public TaskExecutor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(15);
        executor.setMaxPoolSize(15);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("my-async-pool-");
        executor.initialize();
        return executor;
    }
}

下面是我如何调用它们

@Scheduled(fixedRateString = "2000" )
    public void schedule() {
      log.debug("here is the message from schedule");
      asyncMethod();
    }

@Async("asyncTaskExecutor")
public void asyncMethod(){
  log.info("here is the message from async");
}

这是日志

{"thread":"my-sched-pool-1","level":"DEBUG","description":"here is the message from schedule"}
{"thread":"my-sched-pool-1","level":"INFO","description":"here is the message from async"}

正如您所注意到的,两个日志都具有相同的调度程序池。但我希望看到第二个来自 async

如果您从相同的 class 调用 @Async 方法,它们被声明为您有效地绕过了 Spring 的代理机制,这就是您的示例不起作用的原因。尝试从使用 @Service 或任何其他 @Component 类型注释的单独 class 调用方法。

@Service
SomeScheduledClass {

  private final SomeAsyncClass someAsyncClass;

  public SomeScheduledClass(SomeAsyncClass someAsyncClass) {
    this.someAsyncClass = someAsyncClass;
  }

  @Scheduled(fixedRateString = "2000" )
  public void schedule() {
    log.debug("here is the message from schedule");
    someAsyncClass.asyncMethod();
  }
}

@Service
SomeAsyncClass {
  @Async("asyncTaskExecutor")
  public void asyncMethod(){
    log.info("here is the message from async");
  }
}