ファイヤープロジェクト
Bean設定ファイルの分割(Spring1.2.1)
2005-07-26T00:20+09:00   matsu
Bean設定ファイル(ファイヤープロジェクトではbeans.xmlとしてきた)がでかくなった場合は,分割すると管理が容易になる場合がある.この分割方法は,Springでは少なくとも三つあるようなので,試してみた.
例えばXMLBeanFactoryには,二種類のコンストラクタがある.
XmlBeanFactory(Resource resource)
XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) 
前者は今まで使用してきた. 後者は第二引数に親BeanFactoryを持つ. 親BeanFactoryも半ば当然Bean設定ファイルから生成されるから,後者では親BeanFactoryのresourceと自身のresourceの二つのBean設定を読み込むことになる. これが複数の設定ファイルから読み込む最も簡単な例である. サンプルコードを以下に示す.
private static ApplicationContext getApplicationContextType1() {
  logger.info("getApplicationContextType1 start");
  // ClassLoaderがうまくbeans.xmlを見付けられない場合や,
  // jarファイル内にbeans.xmlがある場合は,以下のようにする.
  URL url = HelloApplicationContext.class.getResource("beans1.xml");
  Resource res = new UrlResource(url);
  XmlBeanFactory factory = new XmlBeanFactory(res);

  url = HelloApplicationContext.class.getResource("beans2.xml");
  res = new UrlResource(url);
  factory = new XmlBeanFactory(res, factory);

  GenericApplicationContext ctx = new GenericApplicationContext(factory);
  ctx.refresh();
  return ctx;
}
二つのBean設定ファイルbeans1.xmlとbeans2.xmlを読み込んでいる.
Bean設定ファイルには,要素importがあり,文字通り別のBean設定ファイルを読み込む.
<beans>
  <import resource="beans1.xml"/>
  <import resource="beans2.xml"/>
</beans>
もちろんimportの前後に要素beanを続けることもできる.
<!ELEMENT beans (
        description?,
        (import | alias | bean)*
)>
次の方法との対比のために,ここで読み込むbeans1.xml,beans2.xmlもそれぞれXML文書であることに注意しておく. BeanFactoryをnewする際には,親のBean設定ファイルのみを読み込めばよい.
最後のXMLの解析対象外部実体を使用する方法をあげる. この方法は,XMLの仕様にしたがうもので,Spring独自のものではない. したがって,XMLを設定ファイルとする多くのプログラムでも(XMLパーサが対応していれば)適用できる方法である. より具体的には,Bean設定ファイルのDTDにENTITY要素を記述し,XMLインスタンスにて参照する.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC
  "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" [
  <!ENTITY beans1 SYSTEM "PATH_TO/beans1.inc">
  <!ENTITY beans2 SYSTEM "PATH_TO/beans2.inc">
]>

<beans>
  &beans1;
  &beans2;
</beans>
ENTITY要素内,PATH_TOは,外部実体のXML文書を指定する. 後述するサンプルでは,beans1.inc,beans2.incファイルはjarファイルにある. したがって,
jar:file:/tmp/springsample.jar!/org/fireproject/springsample/beans1.inc
などと記述する. 要素importを使用する場合と同様,BeanFactoryをnewする際には,親のBean設定ファイルのみを読み込めばよい. ただし,分割したファイルはXML文書ではない(解析対象実体). beans1.incを以下に示す.
<?xml version="1.0" encoding="Shift_JIS" ?>
  <bean id="sampleBean1"
        class="org.fireproject.springsample.SampleBean"/>

  <bean id="sampleBean2"
        class="org.fireproject.springsample.SampleBean"/>

  <bean id="sampleBean3"
        class="org.fireproject.springsample.SampleBean"/>
元XML文書で参照された箇所にそのまま展開されるので,このようにルート要素などはない.
以下に,本頁のサンプルのドライバクラスを示す.
前節までの三つの方法でBean設定ファイルを読み込んでいる. サンプルの実行には,beans3.xmlのPATH_TOを先の記述にしたがって修正して
$ ant jar
しなおす必要がある. では実行. まず,要素importによる方法.
$> java -jar springsample.jar 
springsample.HelloApplicationContext:104
  - getApplicationContext start
xml.XmlBeanDefinitionReader:132
  - Loading XML bean definitions from URL [PATH_TO/beans.xml]
xml.XmlBeanDefinitionReader:132
  - Loading XML bean definitions from URL [PATH_TO/beans1.xml]
xml.XmlBeanDefinitionReader:132
  - Loading XML bean definitions from URL [PATH_TO/beans2.xml]
...省略...
次にBeanFactoryをネストする方法.
$> java -jar springsample.jar type1
springsample.HelloApplicationContext:64
  - getApplicationContextType1 start
xml.XmlBeanDefinitionReader:132
  - Loading XML bean definitions from URL [PATH_TO/beans1.xml]
xml.XmlBeanDefinitionReader:132
  - Loading XML bean definitions from URL [PATH_TO/beans2.xml]
...省略...
最後に解析対象外部実体による方法.
$> java -jar springsample.jar type2
springsample.HelloApplicationContext:86
  - getApplicationContextType2 start
xml.XmlBeanDefinitionReader:132
  - Loading XML bean definitions from URL [PATH_TO/beans3.xml]
...省略...
matsu(C)
Since 2002
Mail to matsu