hakobera's blog

技術メモ。たまに雑談

SpringでHotdeploy その3

それでは、XmlWebApplicationContext を継承した、Hotdeploy対応の HotDeployXmlWebApplicationContext クラスを作っていきます。まずは、以下のXmlBeanDefinitionReaderCBP の移植方法です。

package org.zeroturnaround.javarebel.integration.spring;

import org.zeroturnaround.bundled.javassist.ClassPool;
import org.zeroturnaround.bundled.javassist.CtClass;
import org.zeroturnaround.bundled.javassist.CtMethod;
import org.zeroturnaround.javarebel.integration.support.JavassistClassBytecodeProcessor;

/**
 * Registers each XML bean resource with the SpringSingletonReconfigurer.
 */
public class XmlBeanDefinitionReaderCBP extends JavassistClassBytecodeProcessor {

  public void process(ClassPool cp, ClassLoader cl, CtClass ctClass) throws Exception {
    CtMethod m = ctClass.getMethod("loadBeanDefinitions", "(Lorg/springframework/core/io/Resource;)I");   
    m.insertBefore("org.zeroturnaround.javarebel.integration.spring.SpringSingletonReconfigurer" +
    		             ".registerXmlResource($0, $1);");
  }
}

処理としては、XmlBeanDefinitionReader#loadBeanDfintionsメソッドをインターセプトして、リクエスト時にSpring定義ファイルを再読み込みできるように登録している処理になります。

これと同じことをやるには、XmlWebApplicationContext#initBeanDefinitionReaderメソッドをオーバーライドします。contextRecoifgure はまた後日説明しますが、JavaRabelのSpringSingletonReconfigurerクラスとほぼ同じ役割を持ったApplicationContextの再読み込みをサポートしてくれるクラスだと思ってください。

	protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
		if (HotdeployUtil.isHotdeploy()) {
			String[] configLocations = getConfigLocations();
			if (configLocations != null) {
				for (int i = 0; i < configLocations.length; i++) {
					contextReconfigure.registerXmlResource(beanDefinitionReader, configLocations[i]);
				}
			}
		}
	}

これは特に問題ないですね。拡張for文を使っていないのは、一応 JDK1.4でも動くように設計しているためです。JDK1.4だとアノテーションを利用できないので、あんまり需要はないのですが・・・。