Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@PreDestroy method of a Spring singleton bean not called

Tags:

spring

I have a Spring bean defined in beans.xml as follows:

<context:annotation-config />
[...]
<bean id="myBackend" class="mycompany.BackendBean" scope="singleton" />

Inside the bean are 2 methods, which must be executed at the start and before termination of the web application:

public class BackendBean implements IBackend {
    private static final Logger LOGGER = LoggerFactory
            .getLogger(BackendBean.class);

    @PostConstruct
    public void init()
    {
        LOGGER.debug("init");
    }

    @PreDestroy
    public void destroy()
    {
        LOGGER.debug("destroy");
    }
}

When I run the server (mvn jetty:run), I can see the output of the init method in the console, from which I conclude that the init method is executed.

When I press Ctrl-C and Jetty starts to shut down, I don't see the output of the destroy method.

What should I change in order for the destroy method to be executed, when the application is terminated?

like image 988
Dmitrii Pisarenko Avatar asked May 04 '13 10:05

Dmitrii Pisarenko


People also ask

When PostConstruct is called?

The PostConstruct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization. This method MUST be invoked before the class is put into service. This annotation MUST be supported on all classes that support dependency injection.

How can we specify Init method for Spring bean?

To define setup and teardown for a bean, we simply declare the <bean> with initmethod and/or destroy-method parameters. The init-method attribute specifies a method that is to be called on the bean immediately upon instantiation.

What is the use of @PostConstruct in Spring?

When we annotate a method in Spring Bean with @PostConstruct annotation, it gets executed after the spring bean is initialized. We can have only one method annotated with @PostConstruct annotation. This annotation is part of Common Annotations API and it's part of JDK module javax.

How do you define a singleton bean in Spring?

Singleton beans are created when the Spring container is created and are destroyed when the container is destroyed. Singleton beans are shared; only one instance of a singleton bean is created per Spring container. Singleton scope is the default scope for a Spring bean.


2 Answers

For Spring to call @PreDestroy callback method when you application shuts down, you have to add a shutdown hook and close the application context it in. You could attach the hook to JVM using Runtime.getRuntime().addShutdownHook(Thread) or to Jetty if it provides such an API. Here is how you'd do it with JVM shutdown hook:

final ApplicationContext appContext = ... // create your application context 
                         // using one of the various application context classes
Runtime.getRuntime().addShutdownHook(new Thread() {
   public void run() {
       appContext.close();
   }});
like image 57
Abhinav Sarkar Avatar answered Sep 18 '22 13:09

Abhinav Sarkar


Here is a subtle point you need to be aware of with "prototype" scoped beans.

For "prototype" scoped beans, Spring does not call the @PreDestroy method.

Here is the answer from the Spring official reference manual :

Section 1.5.2 (see here)

In contrast to the other scopes, Spring does not manage the complete lifecycle of a prototype bean**: the container instantiates, configures, and otherwise assembles a prototype object, and hands it to the client, with no further record of that prototype instance.

Thus, although initialization lifecycle callback methods are called on all objects regardless of scope, in the case of prototypes, configured destruction lifecycle callbacks are not called. The client code must clean up prototype-scoped objects and release expensive resources that the prototype bean(s) are holding.

To get the Spring container to release resources held by prototype-scoped beans, try using a custom bean post-processor, which holds a reference to beans that need to be cleaned up.

NOTE: This also applies to XML configuration.

like image 28
Sampat Kumar Avatar answered Sep 19 '22 13:09

Sampat Kumar