@PreDestroy method of a Spring singleton bean not called

When you use @Scope("prototype") in your class @PreDestroy isn't working even though if you try to close with context.close(); or context.registerShutdownHook();


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.


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();
   }});

Tags:

Spring