Is @PreDestroy method call granted if we get an Exception in @PostConstruct

2.2k Views Asked by At

I have SpringBoot application which is load some configuration and runs a longtime processing in method annotated with @PostConstruct. There are some resources which should be released if application completed successfully or with an Error.

The question is how to make the most correct release of application resources? Is that enough to make it in @PreDestroy annotated method or I should also catch the exception in @PostConstruct annotated method.

@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

There are 2 best solutions below

0
On BEST ANSWER

PreDestroy Works as callback when the context releases a bean (i.e: on context close). This means that PreDestroy is not coupled with PostConstruct. If the bean exists in the context and it is released, predestroy will be called.

PostConstruct Meant to initialize beans. If it throws an exception the Application will not start.

So, answering your question...

is predestroy-method-call granted if we get an exception in postconstract?

PreDestroy and PostConstruct are not coupled. This means, if PostConstruct got an exception but was managed somehow and the method ended successfully, the bean will be initialized and it will be available in the context. When the time comes and the context is closed, the bean will be released and PreDestroy will be called.

If PostConstruct THROWS an exception, the Bean won't be available at the context (and the app won't start), hence PreDestroy won't be called.

The question is how to make the most correct release of application resources? Is that enough to make it in @PreDestroy annotated method or I should also catch the exception in @PostConstract annotated method?

You should catch the exception and release any unmanaged resource. This also applies to JEE which specifies that as best practice, resources acquired outside of the context must be handled programmatically.

0
On

The @PostConstruct and @PreDestroy annotations allow you to define lifecycle callbacks for your beans (see the documentation for details).

If the @PostConstruct annotated method may throw exceptions, you should catch them and handle the release of the resources accordingly. Consider the following example:

@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");
    }
}

In this situation, the @PreDestroy annotated method won't be executed.