3.6. Customizing the nature of a bean

3.6 Customizing the nature of a bean
3.6.1 Lifecycle callbacks

Beanを生成・破棄するタイミングでコールバックしてくれる。これはBeanPostProcessor で実装しておりカスタマイズ可能。

3.6.1.1 Initialization callbacks,3.6.1.2 Destruction callbacks

インタフェースで実装する場合はInitializingBean/DisposableBeanを実装する。
ただしこのやり方ではSpringに依存するコードになる。それがやな場合はXMLに以下のように書く。



こうするとBeanはSpringが定める特定のインタフェースを実装しなくてもいい。

3.6.1.3 Default initialization and destroy methods

コンテナ単位で指定する場合は、以下のようにするとすべてのBeanに対してこれが適用される。



デフォルトの定義はbean毎の定義で上書き可能。

なおこれらのコールバックはAOPなどが適用される前に呼び出される。

3.6.1.4 Combining lifecycle mechanisms

ライフサイクルの指定はアノテーションでもできる(@PostConstruct,@PreDestroy)
適用順以下のとおり

  1. アノテーション
  2. インタフェースの実装
  3. xmlに定義したinit-method/destroy-method

3.6.1.5 Startup and shutdown callbacks

以下のインタフェースを実装したメソッドは、コンテナの初期化・破棄時に呼び出される。


public interface Lifecycle {
void start();
void stop();
boolean isRunning();
}

このライフサイクルは


public interface LifecycleProcessor extends Lifecycle {
void onRefresh();
void onClose();
}

により管理される。初期化順は順不同だが、depends-onで依存関係がある場合は依存関係が考慮される。

なおSmartLifecycleを使うと、ライフサイクルの初期・破棄順コントロールできるのでよいと思うよ。


public interface Phased {
int getPhase();
}

public interface SmartLifecycle extends Lifecycle, Phased {
boolean isAutoStartup();
void stop(Runnable callback);
}

lifecycleが一番小さいものから初期化される。破棄は逆順。

なおstopにRunnableがわたってきてるのは、シャットダウンプロセスをマルチスレッドで行うため。終わったらRunnable#runを呼んであげること。呼ばないとフェーズごとに30秒でタイムアウト。このあたりの設定は以下で変えられるよ。



//タイムアウト時間をミリ秒指定


リフレッシュとisAutoStartupの当たりはよくわからん買った。あとまわし。

3.6.1.6 Shutting down the Spring IoC container gracefully in non-web applications

スタンドアロンの場合はAbstractApplicationContextのregisterShutdownHookを呼んで、VMのシャットダウンフックに引っ掛けてください


public static void main(final String[] args) throws Exception {
AbstractApplicationContext ctx =
new ClassPathXmlApplicationContext(new String []{"beans.xml"});
ctx.registerShutdownHook();

3.6.2 ApplicationContextAware and BeanNameAware

ApplicationContextをインジェクションしてくれるために実装するインタフェースです。これを実装するとApplicationContextを使ってBeanを取得したり、イベント配信したり、リソース参照できたりする。でもSpringに依存するので、あまりお勧めできない。なおSpring2.5からは@AutowiredでApplicationContextをインジェクトできるようになった。

BeanNameAwareを実装すると自分のBean名が取れるようになる。

3.6.3 Other Aware interfaces

その他Awareシリーズ一覧

インタフェースもらえるもの詳細のセクション
ApplicationContextAware ApplicationContext 省略
ApplicationEventPublisherAware イベントパブリッシャ Section 3.13, “Additional Capabilities of the ApplicationContext”
BeanClassLoaderAware Beanがロードされたクラスローダ Section 3.3.2, “Instantiating beans”
BeanFactoryAware BeanFactory
BeanNameAware Bean名
BootstrapContextAware JCA*1と連携するためのものらしい Chapter 23, JCA CCI
LoadTimeWeaverAware AspectJのWeaver Section 7.8.4, “Load-time weaving with AspectJ in the Spring Framework
MessageSourceAware メッセージリソース? Section 3.13, “Additional Capabilities of the ApplicationContext”
NotificationPublisherAware JMXらしい Section 22.7, “Notifications”
PortletConfigAware Portlet Chapter 18, Portlet MVC Framework
PortletContextAware Portlet Chapter 18, Portlet MVC Framework
ResourceLoaderAware リソースって物扱うらしい Chapter 4, Resources
ServletConfigAware ServletConfig
ServletContextAware ServletContext
大事なことだから二度言うけど、Springに依存するので慎重に。インフラレイアのクラスでだけ使うようにしたほうがいいよ。