使用@PreDestroy关闭@Bean ExecutorService

时间:2018-09-19 09:14:33

标签: java spring javabeans executorservice predestroy

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

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

2 个答案:

答案 0 :(得分:3)

我喜欢内联定义类:

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

答案 1 :(得分:1)

使用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);
        setQueueCapacity(1000);
        return taskExecutor;
    }    
}

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

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