ファイヤープロジェクト
BeanPostProcessor(Spring1.2.1)
2005-07-11T22:10+09:00   matsu
BeanPostProcessorの実装クラスを作成し,ConfigurableBeanFactoryに登録すると,ConfigurableBeanFactoryがbeanを生成した前後に処理を実行させることができるらしいので,試してみた.
以前にBeanFactoryは「標準beanライフサイクル」のためのメソッドを,可能な限り実装しなければならないらしいことを記述した. インタフェースBeanPostProcessorで指定された二つのメソッドも,この「標準beanライフサイクル」のためのメソッドに含まれる.
Object postProcessBeforeInitialization(Object bean, String beanName)
beanの初期化の前に呼び出される.
Object postProcessAfterInitialization(Object bean, String beanName)
beanの初期化の後に呼び出される.
他の「標準beanライフサイクル」を含めたメソッド呼び出し順序は以下になる.
  1. BeanNameAwareの setBeanNameメソッド
  2. BeanFactoryAwareの setBeanFactoryメソッド
  3. ResourceLoaderAwareの setResourceLoaderメソッド(アプリケーションコンテキストで動作しているときのみ)
  4. ApplicationEventPublisherAwareの setApplicationEventPublisherメソッド(アプリケーションコンテキストで動作しているときのみ)
  5. MessageSourceAwareの setMessageSourceメソッド(アプリケーションコンテキストで動作しているときのみ)
  6. ApplicationContextAwareの setApplicationContextメソッド(アプリケーションコンテキストで動作しているときのみ)
  7. ServletContextAwareの setServletContext(アプリケーションコンテキストで動作しているときのみ)
  8. BeanPostProcessorの postProcessBeforeInitializationメソッド
  9. InitializingBeanの afterPropertiesSetメソッド
  10. beans.xmlの要素beanの属性init-methodで指定したメソッド呼び出し
  11. BeanPostProcessorsの postProcessAfterInitializationメソッド
以前(「beanのライフサイクル」の頁)のサンプルでは,InitializingBeanのafterPropertiesSetメソッドと,要素beanの属性init-methodで指定したメソッドの呼び出しを確認したので,これにBeanPostProcessorsのメソッド呼び出しを加えてみる.
以下に本頁のサンプルの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の呼び出し順はそれぞれ登録順に呼び出される. スタック的な呼び出し順ではないことに注意.
matsu(C)
Since 2002
Mail to matsu