私は春のフレームワークを初めて使用し、それを学ぶためのいくつかのチュートリアルから始めました。
次のファイルがあります。
#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
_の違いまたは関係とは
xmlDestroy()
メソッドはシングルトンスコープBeanで呼び出されますが、プロトタイプでは呼び出されません。
SpringはプロトタイプBeanのライフサイクル全体を管理するわけではありません。コンテナーは、プロトタイプオブジェクトをインスタンス化、構成、装飾、およびその他の方法でアセンブルし、クライアントに渡してから、そのプロトタイプインスタンスについての知識を持ちません。リソースを解放するには、カスタムBeanポストプロセッサーを実装してみてください。
Springコンテナがライフサイクル全体を管理するシングルトンBeanとは異なり
この基本的な チュートリアル を見て、異なるコンテキスト間の違いを確認できます
参照 ドキュメント
これは予想される動作です。 SpringがプロトタイプスコープBeanの使用を終了したことを知る方法がないため、Beanの破棄は、プロトタイプスコープBeanのSpringでは管理されません。ドキュメントから:
初期化ライフサイクルコールバックメソッドは、スコープに関係なくすべてのオブジェクトで呼び出されますが、プロトタイプの場合、構成された破棄ライフサイクルコールバックは呼び出されません。
詳細は Springのドキュメント を参照してください。
ApplicationContext
sについては、アプリケーションに最適なものを選択できます。たとえば、XMLまたはアノテーションBeanの設定を使用するかどうか、およびサーブレットコンテナで実行しているかどうかによって異なります。 ApplicationContext
自体は、型階層のルートにあるインターフェースです。
シングルトン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チュートリアル 。
アプリケーションは、10ミリ秒ごとにプロトタイプBeanの新しいインスタンスを要求し、Beanで何かを実行してから、スコープから外すことができます。アプリケーションのシャットダウン時にSpringがそれらをdestroy()しなければならなかった場合、作成されたすべてのプロトタイプBeanへの参照を保持する必要があり、ガベージコレクションされないようにして、メモリリークを引き起こします。
スコープが「プロトタイプ」であるBeanのdestroyイベントも取得しようとしました。だから私は上記のすべての答えを読んで、彼らの答えで試してみます。その結果、プロトタイプBeanであっても破壊を検出する方法がないことに気づきました。
スコープに関係なくすべてのオブジェクトで初期化ライフサイクルコールバックメソッドが呼び出されますが、プロトタイプの場合、構成された破棄ライフサイクルコールバックは呼び出されません。