Springの@PreDestroyと@PostConstructについて。
これはBean定義時代の「init-method」と「destroy-method」のアノテーション。
Scopeをprototypeで作成したBeanについて@PreDestroyはいつ呼ばれんだ?
って気になったので、サンプルを作成して確かめたんでメモる。
まずは、prototypeで作成しない場合の例
対象のComponent
package com.zomu.t.example;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.stereotype.Component;
@Component("testComponent")
public class TestComponent {
@PostConstruct
public void init() {
System.out.println("init.");
}
public void outputMsg() {
System.out.println("msg....");
}
@PreDestroy
public void destroy() {
System.out.println("destroy.");
}
}
実行クラス
package com.zomu.t.example;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestInitDestroy {
public static void main(String[] args) {
ConfigurableApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[] { "ApplicationContext.xml" });
TestComponent tc = (TestComponent) appContext.getBean("testComponent");
tc.outputMsg();
appContext.close();
}
}
結果
init.
msg....
destroy.
おお。ちゃんと呼ばれてますね。
では、prototypeで作成した場合。
対象のComponent
package com.zomu.t.example;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component("testComponent")
@Scope("prototype")
public class TestComponent {
@PostConstruct
public void init() {
System.out.println("init.");
}
public void outputMsg() {
System.out.println("msg....");
}
@PreDestroy
public void destroy() {
System.out.println("destroy.");
}
}
さっきと違うのは、@Scopeでprototype指定しているだけ。
実行すると、、、
結果
init.
msg....
あれ、destroyが呼ばれない。
なんじゃこりゃ。
プロトタイプだから、もうBeanFactoryの知ったこっちゃねぇって事?
じゃー実行クラスで実験してみる。
package com.zomu.t.example;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestInitDestroy {
public static void main(String[] args) {
ConfigurableApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[] { "ApplicationContext.xml" });
TestComponent tc = (TestComponent) appContext.getBean("testComponent");
tc.outputMsg();
appContext.getBeanFactory().destroyBean("testComponent", tc);
appContext.close();
}
}
結果
init.
msg....
destroy.
なるほど。
ちゃんとインスタンスと登録名さえ渡してくれりゃケツ拭きまっせ。ってことっぽい。
めんどいから拭いてくれよー。って思いました。