使用@PreDestroy 关闭@Bean ExecutorService

Shutdown @Bean ExecutorService using @PreDestroy

我有一个 Spring @Configuration class 如下:

@Configuration
public class ExecutorServiceConfiguration {

    @Bean
    public BlockingQueue<Runnable> queue() {
        return ArrayBlockingQueue<>(1000);
    }     

    @Bean
    public ExecutorService executor(BlockingQueue<Runnable> queue) {
        return ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, queue);
    }

    @PreDestroy
    public void shutdownExecutor() {
        // no executor instance
    }
}

我还想指定一个 @PreDestroy 方法来关闭 ExecutorService。但是,@PreDestroy 方法不能有任何参数,这就是为什么我无法将 executor bean 传递给此方法以关闭它的原因。在 @Bean(destroyMethod = "...") 中指定 destroy 方法也不起作用。它允许我指定现有的 shutdownshutdownNow,但不能指定我打算使用的自定义方法。

我知道我可以直接实例化队列和执行器,而不是作为 Spring beans,但我宁愿这样做。

我喜欢定义 类 内联:

@Bean(destroyMethod = "myCustomShutdown")
public ExecutorService executor(BlockingQueue<Runnable> queue) {
    return new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, queue) {
        public void myCustomShutdown() {
            ...
        }
    };
}

使用 ThreadPoolTaskExecutor 默认情况下会执行所有这些操作。

@Configuration
public class ExecutorServiceConfiguration {

    @Bean
    public ThreadPoolTaskExecutor executor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor() {
            protected BlockingQueue<Runnable> createQueue(int queueCapacity) {
                return new ArrayBlockingQueue<>(queueCapacity);
            }
        };
        taskExecutor.setCorePoolSize(1);
        taskExecutor.setMaxPoolSize(1);
        taskExecutor.setKeepAliveSeconds(0);
        taskExecutor.setQueueCapacity(1000);
        return taskExecutor;
    }    
}

这将配置 ThreadPoolExecutor 并在应用程序停止时关闭。

如果您不需要 ArrayBlockingQueue 但可以使用默认的 LinkedBlockingQueue 并且只需要指定队列容量,您可以删除覆盖 createQueue 方法。