1

我有一个 Spring @Configuration 类,如下所示:

@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方法不能有任何参数,这就是为什么我无法将executorbean 传递给该方法以关闭它的原因。指定destroy方法@Bean(destroyMethod = "...")也不起作用。它允许我指定现有的shutdownor shutdownNow,但不能指定我打算使用的自定义方法。

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

4

2 回答 2

4

我喜欢内联定义类:

@Bean(destroyMethod = "myCustomShutdown")
public ExecutorService executor(BlockingQueue<Runnable> queue) {
    return new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, queue) {
        public void myCustomShutdown() {
            ...
        }
    };
}
于 2018-09-19T09:48:19.983 回答
2

使用ThreadPoolTaskExecutorwhich 默认情况下会完成所有这些操作。

@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方法。

于 2018-09-19T10:39:03.113 回答