11

I am studying for the Spring Core certification and I have some dount about on this question finded into the provided study material:

What is the preferred way to close an application context?

I know that if I have something like this:

ConfigurableApplicationContext context = …
// Destroy the application
context.close();

by the use of the close() method on the context objet the ApplicationContext is closed and the application is destroyed.

But I think that this is not the best way that I have to do it.

Reading the official documentation I find that I can also do something like this:

context.registerShutdownHook();

that register a Shutdown Hook with the JVM so it is the JVM that will trigger Spring's close phase before JVM exits. So on JVM exit, Spring's close phase will execute.

On the documentation I can read that: usually not possible to call context.close() because many applications (web applications) run indefinitely But what exactly means this last assertion? why web application run indefinitely?

So my questions are:

  • Can I use this second way to close an application context also with not web application?
  • Is it prefered respect the context.close()?

Tnx

Aleksandr Erokhin
  • 1,904
  • 3
  • 17
  • 32
AndreaNobili
  • 40,955
  • 107
  • 324
  • 596
  • 1
    `many applications (web applications) run indefinitely`..It usually refers to things that happen in an infinite loop unless you stop the process, something like your SocketServer listening to incoming requests. Why do you want to close the WebApplicationContext manually in the first place ? It's usually created at the server start-up and destroyed while server is shutdown – Arkantos Mar 20 '15 at 15:23
  • 1
    A web application never stops because if you do that, site is down. If you want to stop running web application, you will shutdown it (by stopping web server for example). When you do that, the JVM will be stopped too so the "Shutdown Hook with the JVM" is the way to close context with JVM. Why do you want to stop context ? – rlm Mar 20 '15 at 15:26
  • close is used in web applications and shutDownHook is used in standalone applications. Just posted my answer with few more details :) – Arkantos Mar 20 '15 at 15:49

3 Answers3

13

As you are aware that ContextLoaderListener is the one that takes care of initializing and destroying your ApplicationContext, when you shutdown your server, that ContextLoaderListener's contextDestroyed method is invoked.

  public void contextDestroyed(ServletContextEvent event){
    closeWebApplicationContext(event.getServletContext());
    ContextCleanupListener.cleanupAttributes(event.getServletContext());
  }

In that closeWebApplicationContext, they actually call the close method on ApplicationContext like this

  if ((this.context instanceof ConfigurableWebApplicationContext)) {
    ((ConfigurableWebApplicationContext)this.context).close();
  }

This is straight from spring-web-4.1.5.jar. As it is evident from here, they use close to destroy ApplicationContext in web applications.

But registerShutdownHook is used to explicitly shut down IoC container in non-web applications something like a standalone desktop application, specially when you're creating the ApplicationContext manually from ClassPathXmlApplicationContext (or) FileSystemXmlApplicationContext (or) some other types.

This is done to release all resources used by your spring application and to call destroy method on your spring beans if any.

Arkantos
  • 6,530
  • 2
  • 16
  • 36
  • 1
    in StandAlone application e.g. background Service or desktop application, When You enter the main method , you make application context, Now My Question is, If you register the JVM Hook and you exit the main method , Will This destroy the context? – Mubasher Mar 09 '17 at 14:12
8

On the documentation I can read that: usually not possible to call context.close() because many applications (web applications) run indefinitely But what exactly means this last assertion? why web application run indefinitely?

A web application will run as long as the application server that deploys it runs. It is up to the application server (and not to you) to correctly start and stop your application. This means that when the application server is stopped, the servlet context is destroyed. In a Spring application, the ContextLoaderListener class registered in web.xml listens to this event (context destroyed) to properly close the Spring context.

When using Spring outside of an application server (like a standalone application), it is up to you to correctly stop the Spring context. As you said, this can be done by explicitly calling context.close() or registering a shutdown hook (context.registerShutdownHook()) that makes this call for you.

Mangu Singh Rajpurohit
  • 10,806
  • 4
  • 68
  • 97
Tunaki
  • 132,869
  • 46
  • 340
  • 423
  • 1
    ok but is it context.registerShutdownHook() better than to do context.close() ? – AndreaNobili Mar 20 '15 at 15:31
  • Both [`registerShutdownHook()`](http://grepcode.com/file/repo1.maven.org/maven2/org.springframework/spring-context/3.2.3.RELEASE/org/springframework/context/support/AbstractApplicationContext.java#AbstractApplicationContext.registerShutdownHook%28%29) and [`close()`](http://grepcode.com/file/repo1.maven.org/maven2/org.springframework/spring-context/3.2.3.RELEASE/org/springframework/context/ConfigurableApplicationContext.java#ConfigurableApplicationContext.close%28%29) methods call the same code to close the Spring context. You can see that in `AbstractApplicationContext`. – Tunaki Mar 20 '15 at 15:34
0

From https://stackoverflow.com/a/42018369:

The ApplicationContext class doesn't define either of these methods as a part of its interface, but the ConfigurableApplicationContext does define both of these.

From the JavaDoc:

close() -- Close this application context, destroying all beans in its bean factory. registerShutdownHook() -- Register a shutdown hook with the JVM runtime, closing this context on JVM shutdown unless it has already been closed at that time. Basically, AbstractApplicationContext#close() will close, or shutdown, the ApplicationContext at the time it is invoked, while AbstractApplicationContext#registerShutdownHook() will close, or shutdown, the ApplicationContext at a later time when the JVM is shutting down for whatever reason. This will be achieved by utilizing the JVM shutdown hook functionality.

In either case, the actual closing is done by the doClose() method.

If you are curious about why your outputs look so similar, it is because they are effectively doing the same thing, whether you call close() or registerShutdownHook() at line 3 of you example. close() will shutdown right away, and registerShutdownHook() will shutdown just before the JVM will exit, which is pretty much as soon as the method is done being invoked, because it is the last line of code!

aboger
  • 2,214
  • 6
  • 33
  • 47
Emeka
  • 51
  • 1
  • 3