Завершение работы @Bean ExecutorService с использованием @PreDestroy - PullRequest
0 голосов
/ 19 сентября 2018

У меня есть класс 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 не может иметь никаких аргументов, поэтому я не могу передать bean-компонент executor этому методу для его закрытия.Указание метода уничтожения в @Bean(destroyMethod = "...") также не работает.Это позволяет мне указать существующий shutdown или shutdownNow, но не пользовательский метод, который я собираюсь использовать.

Я знаю, что мог бы создать экземпляр очереди и исполнителя напрямую, а не как бины Spring, но я 'Я бы предпочел сделать это таким образом.

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

Используйте 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.

0 голосов
/ 19 сентября 2018

Я люблю определять встроенные классы:

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