Предоставляется ли вызов метода @PreDestroy, если мы получаем исключение в @PostConstract

У меня есть приложение SpringBoot, которое загружает некоторую конфигурацию и выполняет долгую обработку в методе, аннотированном @PostConstract. Есть некоторые ресурсы, которые должны быть освобождены, если приложение завершено успешно или с ошибкой.

Вопрос в том, как сделать максимально корректный выпуск ресурсов приложения? Этого достаточно, чтобы сделать это в аннотированном методе @PreDestroy, или я должен также отловить исключение в аннотированном методе @PostConstract.

@SpringBootApplication
@Import(MyConfiguration.class)
public class MySpringApplication {

    @Autowire
    ProcessRunner processRunner;

    @Autowire
    ResourceBean resourceBean;

    public static void main(String[] args) {
        SpringApplication.run(MySpringApplication.class, args);
    }

    @PostConstruct
    void postConstruct {
        try {
            processRunner.run()
        } catch (Exception ex) {
            // Do we really need this Exception handling to release resource? 
            resourceBean.release();
        }
    }

    @PreDestroy
    void preDestroy() {
        resourceBean.release();
    }
}

2 ответа

Решение

PreDestroy Работает как обратный вызов, когда контекст освобождает компонент (то есть: при закрытии контекста). Это означает, что PreDestroy не связан с PostConstruct. Если bean-компонент существует в контексте и он освобождается, вызывается predestroy.

PostConstruct Предназначен для инициализации bean-компонентов. Если выдается исключение, приложение не запустится.

Итак, отвечая на ваш вопрос...

будет ли вызов predestroy-method-call, если мы получим исключение в постконспекте?

PreDestroy и PostConstruct не связаны. Это означает, что если PostConstruct получил исключение, но каким-то образом управлялся и метод успешно завершился, bean-компонент будет инициализирован и будет доступен в контексте. Когда придет время и контекст закроется, компонент будет выпущен, и будет вызван PreDestroy.

Если PostConstruct БРОСИТ исключение, Бин не будет доступен в контексте (и приложение не запустится), поэтому PreDestroy не будет вызываться.

Вопрос в том, как сделать максимально корректный выпуск ресурсов приложения? Этого достаточно, чтобы сделать это в аннотированном методе @PreDestroy, или я должен также поймать исключение в аннотированном методе @PostConstract?

Вы должны поймать исключение и освободить любой неуправляемый ресурс. Это также относится к JEE, который указывает, что в качестве передового опыта ресурсы, полученные вне контекста, должны обрабатываться программно.

@PostConstruct а также @PreDestroy аннотации позволяют вам определять обратные вызовы жизненного цикла для ваших компонентов (подробности см. в документации).

Если @PostConstructАннотированный метод может выдавать исключения, вы должны перехватывать их и обрабатывать освобождение ресурсов соответственно. Рассмотрим следующий пример:

@SpringBootApplication
public class MySpringApplication {

    public static void main(String[] args) {
        SpringApplication.run(MySpringApplication.class, args);
    }

    @PostConstruct
    public void init() {
        System.out.println("@PostConstruct method executed");
        throw new RuntimeException();
    }

    @PreDestroy
    public void destroy() {
        System.out.println("@PreDestroy method executed");
    }
}

В этой ситуации @PreDestroy Аннотированный метод не будет выполнен.

Другие вопросы по тегам