web-dev-qa-db-ja.com

Spring Bean destroy-method、シングルトン、およびプロトタイプスコープ

私は春のフレームワークを初めて使用し、それを学ぶためのいくつかのチュートリアルから始めました。

次のファイルがあります。

#MainProgram.Java

_package test.spring;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainProgram {
        public static void main(String[] args) {
              AbstractApplicationContext context = 
                              new ClassPathXmlApplicationContext("Bean.xml");     
              HelloSpring obj = (HelloSpring) context.getBean("helloSpring");
              obj.setMessage("My message");
              obj.getMessage();
              context.registerShutdownHook();

        }
 }
_

#HelloSpring.Java

_package test.spring;

public class HelloSpring   {
     private String message;

     public void setMessage(String message){
      this.message  = message;
      System.out.println("Inside setMessage");
   }

   public void getMessage(){
      System.out.println("Your Message : " + this.message);
   }

   public void xmlInit() {
    System.out.println("xml configured  initialize");
   } 

    public void xmlDestroy() {
    System.out.println("xml configured destroy");
    }

  }
_

#Bean.xml

_    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

     <bean id="helloSpring" class="test.spring.HelloSpring" 
          scope="prototype" init-method="xmlInit" destroy-method="xmlDestroy">

     </bean>
     </beans>
_

_scope="singleton"_を使用すると、出力は次のようになります。

_ xml configured  initialize
 Inside setMessage
 Your Message : My message
 xml configured destroy
_

_scope="prototype"_を使用すると、出力は次のようになります。

_ xml configured  initialize
 Inside setMessage
 Your Message : My message
_

xmlDestroy()メソッドはsingletonスコープBeanで呼び出されますが、prototypeでは呼び出されません。

これは正しいです?もしそうなら、考えられる理由は何でしょうか?

また、私はいくつかのクエリを持っています、

_ApplicationContext , AbstractApplicationContext and ClassPathXmlApplicationContext_の違いまたは関係とは

22

xmlDestroy()メソッドはシングルトンスコープBeanで呼び出されますが、プロトタイプでは呼び出されません。

SpringはプロトタイプBeanのライフサイクル全体を管理するわけではありません。コンテナーは、プロトタイプオブジェクトをインスタンス化、構成、装飾、およびその他の方法でアセンブルし、クライアントに渡してから、そのプロトタイプインスタンスについての知識を持ちません。リソースを解放するには、カスタムBeanポストプロセッサーを実装してみてください。

Springコンテナがライフサイクル全体を管理するシングルトンBeanとは異なり

この基本的な チュートリアル を見て、異なるコンテキスト間の違いを確認できます

参照 ドキュメント

43
Manish Singh

これは予想される動作です。 SpringがプロトタイプスコープBeanの使用を終了したことを知る方法がないため、Beanの破棄は、プロトタイプスコープBeanのSpringでは管理されません。ドキュメントから:

初期化ライフサイクルコールバックメソッドは、スコープに関係なくすべてのオブジェクトで呼び出されますが、プロトタイプの場合、構成された破棄ライフサイクルコールバックは呼び出されません。

詳細は Springのドキュメント を参照してください。

ApplicationContextsについては、アプリケーションに最適なものを選択できます。たとえば、XMLまたはアノテーションBeanの設定を使用するかどうか、およびサーブレットコンテナで実行しているかどうかによって異なります。 ApplicationContext自体は、型階​​層のルートにあるインターフェースです。

2
hertzsprung

シングルトンBeanは、アプリケーションコンテキストにそのBeanのインスタンスが1つだけ存在することを意味します。これは、次のようなことをした場合を意味します。

HelloSpring obj = (HelloSpring) context.getBean("helloSpring");
    obj.setMessage("My message");
    System.out.printIn(obj.getMessage());
    HelloSpring anotherObj = (HelloSpring) context.getBean("helloSpring");
    System.out.printIn(anotherObj.getMessage());

コンソール出力に「マイメッセージ」が2回表示されます。

プロトタイプBeanの場合、アプリケーションコンテキストからそれらの1つを取得しようとするたびに新しいインスタンスが取得されるため、上記のコードを再度実行すると、2番目のコンソール出力は「null」になります。

コンテナーはプロトタイプBeanのdestroyメソッドを呼び出す必要がないため、呼び出す必要はなく、動作は正しいです。

上記のクラスの違いは、それらがそれぞれインターフェイス、抽象クラス、具象クラスであることであり、その概念をよりよく理解するために、ここでJavaの公式Oracleドキュメントを読むことをお勧めします- Oracle Javaチュートリアル

2
Can Yegane

アプリケーションは、10ミリ秒ごとにプロトタイプBeanの新しいインスタンスを要求し、Beanで何かを実行してから、スコープから外すことができます。アプリケーションのシャットダウン時にSpringがそれらをdestroy()しなければならなかった場合、作成されたすべてのプロトタイプBeanへの参照を保持する必要があり、ガベージコレクションされないようにして、メモリリークを引き起こします。

2

スコープが「プロトタイプ」であるBeanのdestroyイベントも取得しようとしました。だから私は上記のすべての答えを読んで、彼らの答えで試してみます。その結果、プロトタイプBeanであっても破壊を検出する方法がないことに気づきました。

スコープに関係なくすべてのオブジェクトで初期化ライフサイクルコールバックメソッドが呼び出されますが、プロトタイプの場合、構成された破棄ライフサイクルコールバックは呼び出されません。

ここを参照( https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-factory-scopes-prototype

0
Liu Zhe