ファイヤープロジェクト
bean設定での継承関係(Spring1.2.1)
2005-06-28T00:00+09:00   matsu
bean設定ファイルにて,属性abstractや属性parentを使用することによって,Javaクラスのような継承パターンを実現できる.これを使用すると設定ファイルがすっきりする場合がある.
本頁のサンプルのbeans.xmlを以下に示す.
上記beans.xmlのbean設定では,以下のような継承関係がある.
継承関係やabstractを表現するため,クラス図っぽく書いてみた. で,childDefitnition1とchildDefinition2はparentDefinitionを継承している. これは子bean側の要素beanの属性parentにて,親beanのidを指定することで表現する.
  <bean id="childDefinition1"
        class="org.fireproject.springsample.ChildBean"
	singleton="false"
        parent="parentDefinition">
...省略...
  <bean id="childDefinition2"
        class="org.fireproject.springsample.ChildBean"
	singleton="false"
        parent="parentDefinition"
        init-method="init2">
...省略...
同様にchildDefinition3はabstractParentDefinitionを継承している.
  <bean id="childDefinition3"
        class="org.fireproject.springsample.ChildBean"
	singleton="false"
        parent="abstractParentDefinition">
さらにabstractparentDefinitionはabstractであり,beanFactoryによってインスタンス化されることはない. これはabstractなbeanを設定する要素beanの属性abstractをtrueに指定することによって表現する.
  <bean id="abstractParentDefinition"
        class="org.fireproject.springsample.AbstractParent"
        abstract="true">
前節にてbean設定の親子(継承)関係の表現方法を記述した(※). 子bean設定は自動的に親bean設定を継承する. この仕組みよって,設定ファイルが簡潔になる場合がある. 例えば,先のbeans.xmlにて
  
    Parent constructor arg
    Parent Value1
    Parent Value2
  

  
  
とある. 子beanであるchildDefinition1には,値の設定がないが,親beanであるparentDefinitionで指定されている値の設定がchildDefinition1にも適用される. したがって,childDefinition1をインスタンス化する際にコンストラクタに引数"Parent constructor arg"が渡され,さらにsetValue1,setValue2が呼び出され,それぞれ値が設定される. 設定のオーバーライドも可能である. 先のchildDefinition2では,親の設定をオーバーライドしている.
  <bean id="childDefinition2"
        class="org.fireproject.springsample.ChildBean"
	singleton="false"
        parent="parentDefinition"
        init-method="init2">
    <constructor-arg index="0"><value>Child constructor arg</value></constructor-arg>
    <property name="value2"><value>Child Value2</value></property>
  </bean>
上ではコンストラクタの引数と,setValue2呼び出しの引数は,子側で指定のものが使用される. さらにinit-mothod指定も子側に指定があるので,オーバーライドされてこちらが使用される. setValue1呼び出しは,子側に指定がないので,親側での指定のものが使用される. サンプルを実行すると,上記を確認できる. まずChildBeanのソースを以下に示す.
これを踏まえて実行.
springsample.HelloBeanFactory:31 - ===== childDefinition1 =====
springsample.SampleBean:16 - Parent constructor arg
springsample.ChildBean:11 - ChildBean
springsample.SampleBean:24 - init
springsample.ChildBean:16 - init
springsample.HelloBeanFactory:32 -
  org.fireproject.springsample.ChildBean
  [value1 = Parent Value1 / value2 = Parent Value2]
springsample.HelloBeanFactory:31 - ===== childDefinition2 =====
springsample.SampleBean:16 - Child constructor arg
springsample.ChildBean:11 - ChildBean
springsample.ChildBean:20 - init2
springsample.HelloBeanFactory:32 -
  org.fireproject.springsample.ChildBean
  [value1 = Parent Value1 / value2 = Child Value2]
springsample.HelloBeanFactory:31 - ===== childDefinition3 =====
springsample.SampleBean:16 - Child constructor arg
springsample.ChildBean:11 - ChildBean
springsample.HelloBeanFactory:32 -
  org.fireproject.springsample.ChildBean
  [value1 = AbstractParent Value1 / value2 = Child Value3]

	
※ bean設定の継承関係は,Javaクラスの継承関係とマッピングするのが自然な場合が多いような気もするが,ここではあくまで設定の継承関係である点に注意. 必要なアクセサがそろっていれば,Javaクラスでの継承関係とbean設定の継承関係をマッピングさせくても動作はする.
matsu(C)
Since 2002
Mail to matsu