BeanPostProcessor(Spring1.2.1)
BeanPostProcessorの実装クラスを作成し,ConfigurableBeanFactoryに登録すると,ConfigurableBeanFactoryがbeanを生成した前後に処理を実行させることができるらしいので,試してみた.
以前にBeanFactoryは「標準beanライフサイクル」のためのメソッドを,可能な限り実装しなければならないらしいことを記述した.
インタフェースBeanPostProcessorで指定された二つのメソッドも,この「標準beanライフサイクル」のためのメソッドに含まれる.
- Object postProcessBeforeInitialization(Object bean, String beanName)
- beanの初期化の前に呼び出される.
- Object postProcessAfterInitialization(Object bean, String beanName)
- beanの初期化の後に呼び出される.
- BeanNameAwareの setBeanNameメソッド
- BeanFactoryAwareの setBeanFactoryメソッド
- ResourceLoaderAwareの setResourceLoaderメソッド(アプリケーションコンテキストで動作しているときのみ)
- ApplicationEventPublisherAwareの setApplicationEventPublisherメソッド(アプリケーションコンテキストで動作しているときのみ)
- MessageSourceAwareの setMessageSourceメソッド(アプリケーションコンテキストで動作しているときのみ)
- ApplicationContextAwareの setApplicationContextメソッド(アプリケーションコンテキストで動作しているときのみ)
- ServletContextAwareの setServletContext(アプリケーションコンテキストで動作しているときのみ)
- BeanPostProcessorの postProcessBeforeInitializationメソッド
- InitializingBeanの afterPropertiesSetメソッド
- beans.xmlの要素beanの属性init-methodで指定したメソッド呼び出し
- BeanPostProcessorsの postProcessAfterInitializationメソッド
以下に本頁のサンプルのbeans.xmlを示す.
内容は以前(「beanのライフサイクル」の頁)と同じで,要素beanに属性init-methodとdestroy-methodが指定されている.
また,beanクラスであるLifeCycleSampleBeanは,InitializingBean,DisposableBeanを実装している.
この辺りも変更はない.
変更点は,サンプルのドライバクラスである.
ポイントは,BeanPostProcessorを登録しているところである.
ではサンプルを実行してみる.
// BeanPostProcessorの登録
BeanPostProcessor beanPostProcessor1 = new SampleBeanPostProcessor("1");
beanFactory.addBeanPostProcessor(beanPostProcessor1);
BeanPostProcessor beanPostProcessor2 = new SampleBeanPostProcessor("2");
beanFactory.addBeanPostProcessor(beanPostProcessor2);
このようにBeanPostProcessorは複数登録できる.
postProcessBeforeInitializationと
postProcessAfterInitializationのそれぞれが登録した順番に呼び出される.
サンプルのBeanPostProcessorの実装クラスを以下に示す.
$> java -jar springsample.jar
...省略...
support.AbstractBeanFactory:219
- Creating shared instance of singleton bean 'lifeCycleSampleBean'
springsample.LifeCycleSampleBean:17 - constructor of LifeCycleSampleBean.
springsample.LifeCycleSampleBean:21 - setValue.
springsample.SampleBeanPostProcessor:27
- postProcessBeforeInitialization. [name/beanName/bean] =
[1/lifeCycleSampleBean/org.fireproject.springsample.LifeCycleSampleBean@86fe26]
springsample.SampleBeanPostProcessor:27
- postProcessBeforeInitialization. [name/beanName/bean] =
[2/lifeCycleSampleBean/org.fireproject.springsample.LifeCycleSampleBean@86fe26]
springsample.LifeCycleSampleBean:35 - afterPropertiesSet.
springsample.LifeCycleSampleBean:43 - initMethod.
springsample.SampleBeanPostProcessor:21
- postProcessAfterInitialization. [name/beanName/bean] =
[1/lifeCycleSampleBean/org.fireproject.springsample.LifeCycleSampleBean@86fe26]
springsample.SampleBeanPostProcessor:21
- postProcessAfterInitialization. [name/beanName/bean] =
[2/lifeCycleSampleBean/org.fireproject.springsample.LifeCycleSampleBean@86fe26]
springsample.HelloBeanFactory:45 - factory.close.
support.AbstractApplicationContext:499 - Closing application context
[org.springframework.context.support.GenericApplicationContext;hashCode=7804298]
support.AbstractBeanFactory:525 - Destroying singletons in factory
{org.springframework.beans.factory.xml.XmlBeanFactory defining beans
[lifeCycleSampleBean]; root of BeanFactory hierarchy}
springsample.LifeCycleSampleBean:51 - destroy.
springsample.LifeCycleSampleBean:59 - destroyMethod.
postProcessBeforeInitializationと
postProcessAfterInitializationの呼び出し順はそれぞれ登録順に呼び出される.
スタック的な呼び出し順ではないことに注意.

