web-dev-qa-db-ja.com

SpringでApplicationContextをどの程度正しく閉じますか?

私はSpringCore認定の勉強をしていますが、提供された学習資料にあるこの質問については、いくつかの疑問があります。

アプリケーションコンテキストを閉じるための好ましい方法は何ですか?

私はこのようなものがあれば知っています:

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

contextオブジェクトでclose()メソッドを使用すると、ApplicationContextが閉じられ、アプリケーションが破棄されます。

しかし、これは私がしなければならない最善の方法ではないと思います。

公式ドキュメントを読むと、次のようなこともできることがわかりました。

_context.registerShutdownHook();
_

that シャットダウンフックをJVMに登録するしたがって、JVMが終了する前にSpringのクローズフェーズをトリガーするのはJVMです。したがって、JVMの終了時に、Springのクローズフェーズが実行されます。

ドキュメントで私はそれを読むことができます:多くのアプリケーション(Webアプリケーション)が無期限に実行されるため、通常はcontext.close()を呼び出すことはできませんしかし、この最後のアサーションは正確にはどういう意味ですか?なぜWebアプリケーションが無期限に実行されるのですか?

だから私の質問は:

  • この2番目の方法を使用して、Webアプリケーション以外でもアプリケーションコンテキストを閉じることはできますか?
  • context.close()を尊重することをお勧めしますか?

Tnx

9
AndreaNobili

ContextLoaderListenerがApplicationContextの初期化と破棄を処理することを知っているので、サーバーをシャットダウンすると、そのContextLoaderListenerのcontextDestroyedメソッドが呼び出されます。

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

そのcloseWebApplicationContextでは、実際には次のようにApplicationContextでcloseメソッドを呼び出します。

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

これはspring-web-4.1.5.jarから直接です。ここから明らかなように、彼らはcloseを使用してWebアプリケーションのApplicationContextを破棄します。

ただし、registerShutdownHookは、スタンドアロンデスクトップアプリケーションなどの非WebアプリケーションでIoCコンテナを明示的にシャットダウンするために使用されます。特に、ClassPathXmlApplicationContext(または)FileSystemXmlApplicationContext(または)他のタイプから手動でApplicationContextを作成する場合に使用されます。

これは、Springアプリケーションで使用されているすべてのリソースを解放し、SpringBeanでdestroyメソッドを呼び出すために行われます。

12
Arkantos

ドキュメントで私はそれを読むことができます:多くのアプリケーション(Webアプリケーション)が無期限に実行されるため、通常context.close()を呼び出すことはできませんしかし、この最後のアサーションは正確にはどういう意味ですか?なぜWebアプリケーションが無期限に実行されるのですか?

Webアプリケーションは、それをデプロイするアプリケーションサーバーが実行されている限り実行されます。アプリケーションを正しく開始および停止するのは、アプリケーションサーバーの責任です(ユーザーの責任ではありません)。これは、アプリケーションサーバーが停止すると、サーブレットコンテキストが破棄されることを意味します。 Springアプリケーションでは、_web.xml_に登録されている ContextLoaderListener クラスがこのイベントをリッスンし(コンテキストが破棄され)、Springコンテキストを適切に閉じます。

アプリケーションサーバーの外部でSpringを使用する場合(スタンドアロンアプリケーションなど)、Springコンテキストを正しく停止するのはユーザーの責任です。あなたが言ったように、これは明示的にcontext.close()を呼び出すか、この呼び出しを行うシャットダウンフック(context.registerShutdownHook())を登録することによって行うことができます。

8
Tunaki