Bean 定義の継承

Bean 定義には、コンストラクター引数、プロパティ値、初期化メソッド、静的ファクトリメソッド名などのコンテナー固有の情報など、多くの構成情報を含めることができます。子 Bean 定義は、親定義から構成データを継承します。子定義は、必要に応じて一部の値をオーバーライドしたり、他の値を追加したりできます。親と子の Bean 定義を使用すると、入力を大幅に節約できます。事実上、これはテンプレートの形式です。

ApplicationContext インターフェースをプログラムで操作する場合、子 Bean 定義は ChildBeanDefinition クラスで表されます。ほとんどのユーザーは、このレベルではそれらを操作しません。代わりに、ClassPathXmlApplicationContext などのクラスで Bean 定義を宣言的に構成します。XML ベースの構成メタデータを使用する場合、parent 属性を使用して子 Bean 定義を指定し、この属性の値として親 Bean を指定できます。次の例は、その方法を示しています。

<bean id="inheritedTestBean" abstract="true"
		class="org.springframework.beans.TestBean">
	<property name="name" value="parent"/>
	<property name="age" value="1"/>
</bean>

<bean id="inheritsWithDifferentClass"
		class="org.springframework.beans.DerivedTestBean"
		parent="inheritedTestBean" init-method="initialize">  (1)
	<property name="name" value="override"/>
	<!-- the age property value of 1 will be inherited from parent -->
</bean>
1parent 属性に注意してください。

子 Bean 定義は、指定されていない場合は親定義の Bean クラスを使用しますが、オーバーライドすることもできます。後者の場合、子 Bean クラスは親と互換性がなければなりません(つまり、親のプロパティ値を受け入れる必要があります)。

子 Bean 定義は、新しい値を追加するオプションを使用して、親からスコープ、コンストラクター引数値、プロパティ値、メソッドオーバーライドを継承します。指定したスコープ、初期化メソッド、破棄メソッド、static ファクトリメソッド設定は、対応する親設定をオーバーライドします。

残りの設定は常に子定義から取得されます: 依存、オートワイヤーモード、依存関係チェック、シングルトン、遅延初期化。

前の例では、abstract 属性を使用して、親 Bean 定義を抽象として明示的にマークしています。親定義でクラスが指定されていない場合、次の例に示すように、親 Bean 定義を abstract として明示的にマークする必要があります。

<bean id="inheritedTestBeanWithoutClass" abstract="true">
	<property name="name" value="parent"/>
	<property name="age" value="1"/>
</bean>

<bean id="inheritsWithClass" class="org.springframework.beans.DerivedTestBean"
		parent="inheritedTestBeanWithoutClass" init-method="initialize">
	<property name="name" value="override"/>
	<!-- age will inherit the value of 1 from the parent bean definition-->
</bean>

親 Bean は不完全であるため、単独でインスタンス化することはできません。また、明示的に abstract としてマークされています。定義が abstract の場合、子定義の親定義として機能する純粋なテンプレート Bean 定義としてのみ使用できます。別の Bean の ref プロパティとして参照するか、親 Bean ID で明示的な getBean() 呼び出しを行うことにより、そのような abstract 親 Bean を単独で使用しようとすると、エラーが返されます。同様に、コンテナーの内部 preInstantiateSingletons() メソッドは、抽象として定義されている Bean 定義を無視します。

ApplicationContext は、デフォルトですべてのシングルトンを事前にインスタンス化します。(少なくともシングルトン Bean の場合)テンプレートとしてのみ使用する(親)Bean 定義があり、この定義がクラスを指定する場合、abstract 属性を true に設定する必要があります。そうでない場合、アプリケーションコンテキストは、実際に abstract Bean を事前にインスタンス化(試行)します。