2013-08-29 15 views
9

は、私が作成したJava ExecutorServiceで構成されますSpring管理Beanの使用コマンドラインアプリケーションがあります。今SpringでExecutorサービスを正しくシャットダウンする方法は?

ExecutorService service = Executors.newFixedThreadPool(4); 

を、私のアプリケーションがシャットダウンしたとき、私はシャットダウンに私のサービスをしたいので、私は私の豆を作りましたDisposableBeanインタフェースを実装し、そのように破壊する方法があります。そして、私は春のコンテキストにシャットダウンフックを登録するような何かをしたくなるかもしれません

public void destroy(){ 
    service.shutdown(); 
} 

。しかし、私はこれがうまくいかないことを知りました。シャットダウンフックは、ExecutorService.shutdown()メソッドが呼び出される前に呼び出されないため、古典的なキャッチ22の問題が発生します。アプリケーションが実行されている間にCtrl-Cを押した場合など)。何らかの理由でJUnitの中から何らかの理由で正常に動作しているように見えるので、これは私の単体テストを免れました.JUnitはまだ私を困惑させています。

私が今までに見つけた解決策は、メイン機能を終了する直前にApplicationContext.close()を明示的に呼び出すことでした。私は、これにはより良い解決策があるのか​​、Springによって管理される柔軟なスレッドプールを持つためのベストプラクティスがあるのだろうかと思いました。また、私のbeanがでない場合は、はSpringによって直接管理されますが、Springによって管理されるBeanによって作成されますか?私はちょうどdestroy()へのコールをカスケードする必要がありますか?これは非常にエラーが発生しやすいでしょうか?

コメント、提案、さらに読む、RTFM、魔法のレシピをありがとう。

ありがとうございます!

ExecutorService service = Executors.newFixedThreadPool(4); 

これに置き換えることができます: - そしてそれができる

<bean id="service" class="java.util.concurrent.Executors" 
     factory-method="newFixedThreadPool" destroy-method="shutdown"> 
    <constructor-arg value="4"/> 
</bean> 

春のコンテキストは、その後、より直接的に、あなたのエグゼキュータのサービスのシャットダウンを管理

+0

PS:コマンドラインアプリケーションをTomcatなどのアプリケーションサーバーに移動する場合はどうすればよいですか?何か変わるでしょうか? –

+0

タイトルとあなたのPSを含めて、私は7 *(7!)の疑問符を数えます。 :-)あなたが特定の質問を1つだけ聞くと、より良い回答が得られるかもしれません。 – Keith

答えて

24

は、あなたがこのことを知っていますより簡単に再利用できる。

+0

私はそれを認識しています。しかし、実行時までに必要なBeanの数や特定のBeanの定義が外部ソース(データベースなど)から来るかどうかなど、コンフィグレーションを通じてではなく、プログラムで豆をプログラムで作成する場合もあります。またはメッセージキュー。 –

+0

私のupvoteをカウントダウン、それは無効です。これは動作しませんが、Spring Contextの初期化中に 'InvalidArgumentException'が発生します。 – Powerslave

1

SpringのTaskExecutorの使用を検討してください。これはスレッドプールで構成できます。公式春のドキュメント、パー http://static.springsource.org/spring/docs/3.0.x/reference/scheduling.html

+0

私はそれが私のユースケースに合うとは思わない。私は多くのタスク間の同期(例えば障壁)が必要であり、エグゼキュータやカスタムタスクを明示的に使用してより多くの制御を行うことができます。 –

1

@BeandestroyMethod分野のため、アノテーションベースの設定を使用して、春のデフォルトの動作は、アプリケーションコンテキストが閉じているときに自動的にcloseまたはshutdownという名前のパブリック、引数なしのメソッドを呼び出すことです。ユーザの利便性として

、容器は@Beanメソッドから返されたオブジェクトに対して destroyメソッドを推測しようとします。 の例では、@BeanメソッドがApache Commons DBCP BasicDataSourceを返すと、コンテナはclose()メソッド がそのオブジェクトで利用可能であることを認識し、自動的に destroyMethodとして登録します。この 'destroyメソッドの推論'は現在、 'close'または 'shutdown'というパブリックな引数なしメソッドだけを検出する に制限されています。 メソッドは、継承階層の任意のレベルで宣言でき、@Beanメソッド の戻り型に関係なく、 が検出されます。、生成時にBeanインスタンス自身 に対して検出が反映されます)。

再反復するために破壊する方法が明示的に設定されていない場合、これは、アノテーション・ドリブン設定のデフォルトの動作です。この動作が望ましくない場合には、明示的に空の文字列にする方法を破壊するこの設定「機能」無効にします:、特定の@Beanための方法の推論を破壊する値として 空の文字列を指定し、例えば無効にするには

を@Bean(destroyMethod = "")。 DisposableBeanおよびCloseable/AutoCloseableインターフェイスは にもかかわらず検出され、対応する破棄/終了メソッド が呼び出されることに注意してください。一方

XML構成を使用する場合、これはないデフォルトの動作です...パリティを達成するために、destroy-methodは、明示的に(inferred)に設定することができます。詳細については、公式ドキュメントのDestruction callbacksおよびDefault initialization and destroy methodsセクションを参照してください。

関連する問題