Springでbeanの継承と抽象コードの例


私たちはSpringを使う時、一般的なデザインの時に必ず使う抽象類です。Springではこれらの抽象的なビーンをどう配置しますか?下を見てください
2つのbeanの間の構成情報が非常に類似している場合、重複構成動作を低減するために継承を利用することができる。
継承とは、親beanから継承部分構成情報を定義することができ、特定の構成情報をカバーすることもでき、またはいくつかの構成を追加することができるサブbean定義である。継承構成を使うと、多くの構成作業が節約されます。実用的なアプリケーションでは、汎用構成はテンプレートとして構成され、サブbeanの継承が可能です。
abstract属性を使う
前述のように、一般的な構成はテンプレートとして構成されますが、テンプレートは実用化を必要とせず、サブbean定義のテンプレートとしてのみ使用されます。Apple Conteetはデフォルトですべてのsingleton beanを初期化します。abstract属性を使用すると、テンプレートbeanが初期化されるのを防ぐことができます。abstract属性はtrueのbeanで抽象的なbeanと呼ばれ、容器はすべての抽象的なbean定義を無視し、初期化時に抽象的なbeanを初期化しない。abstract属性が定義されていない場合、この属性はデフォルトでfalseです。以下の構成ファイルはテンプレートとして使用される抽象的なbeanを定義しています。

public class SteelAxe implements Axe
{
//count      ,    chop       1
private int count = 0;
public SteelAxe(){
System.out.println("Spring     bean: SteelAxe   .. .");
}
//     
public String chop(){
return "      " + ++count;
}
}
public class Chinese implements Person
//  Axe     ,         
private Axe axe;
//      
public Chinese(){
System.out.println("Spring     bean: Chinese   ... ");
}
//       setter   
public void setAxe( Axe axe){
System.out.pr ntln (" Spring         ...");
this.axe = axe;
}
//  Person    useAxe   
public void useAxe(){
System.out.println(axe.chop());
}
}

<?xml version="1.0" encoding="gb2312"?>
<!   Spring      dtd>
<lDOCTYPE beans PUBL C "-//SPRING//DTD BEAN//EN"
''http://www.springframework.org/dtd/spring-beans.dtd''>
<! Spring          〉
<beans>
<bean id="steelAxe" class="lee.SteelAxe"/>
<!…   abstract      bean    bean-->
<bean id="chineseTemplate" class="lee.Chinese" abstract="true">
<!           〉
<property name="axe">
<ref local="steelAxe"/>
</property>
</bean>
</beans>
配置ファイルから、抽象的なbeanの定義は普通のbeanの定義とほとんど違いがなく、abstract属性を増やすだけがtrueであることが分かりますが、メインプログラムの実行結果には著しい違いがあります。次のメインプログラムはAppliction ContectをSpring容器として、ApppliationContectはデフォルトですべてのsingleton beanを初期化します。そのメインプログラムの部分は以下の通りです。

public class BeanTest
{
public static void main(String[] args)throws Exception{
ApplicationContext ctx = new FileSysternXmlApplicationContext("bean.xml");
}
}
//           ApplicationContext,    ApplicationContext ,     singleton bean。
プログラム実行結果は以下の通りです。
Spring实例化依存bean:Steel Axe例.
容器はchinese Template beanを実例化していません。abstractという宣言を無視したbeanoはabstract属性の定義をキャンセルすると、プログラム実行結果は以下の通りです。
Spring实例化依存bean:SteeelAxe実~J…
Springの実例.
Spring実行依存関係注入…
抽象的なbeanはbeanテンプレートであり、容器は抽象的なbean定義を無視してしまうので、抽象的なbeanは実用化されないことが分かります。しかし、抽象的なbeanは、実用化する必要がないので、クラスの属性がないことができます。以下の設定ファイルも有効です。

<?xml version="1.0" e coding="gb2312"?>
<!   Spring      dtd>
<!DOCTYPE beans PUBLIC "-/!SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd''>
<! -- Spring         -->
<beans>
<bean id="steelAxe" class="lee.SteelAxe"/>
<!   abstract      bean    bean,  bean     class    〉
<bean id="chineseTemplate" abstract="true">
<!…           〉
<property name="axe">
<ref local="steelAxe"/>
</property>
</bean〉
</beans>
抽象的なbeanは実用化できません。getBenを通じて抽象的なbeanを獲得することもできないし、他のbeanのref属性値を抽象的なbeanを指すこともできません。したがって、抽象的なbeanを実践化しようとすると、いずれも誤りを招くことになります。
定義子bean
私たちはparent属性値を指定したbeanをサブbeanと呼びます。parentは子beanのテンプレートを指して、父beanといいます。サブbeanは、実現類、コンストラクタパラメータ、属性値を父beanから継承することができます。また、新たな値を追加することもできます。init-method、destroy-method、およびfactory-methodの属性が指定されている場合、それらは親beanの定義をカバーします。子供beanは親beanから以下の属性を継承できません。depends-on、atowire、dependency-check、singleton、lazy-nit。これらの属性はサブbean定義から取得されます。または標準値を使用します。parent属性を設定することにより、サブbeanを定義し、parent属性値は親bean idとなります。上記のプロファイルを修正して、サブbean定義を追加しました。

<?xml version="1.0" encoding="gb2312"?>
<!   Spring      dtd>
<lDOCTYPE beans PUBL C "-//SPRING//DTD BEAN//EN"
''http://www.springframework.org/dtd/spring-beans.dtd''>
<!-- Spring          〉
<beans>
<bean id="steelAxe" class="lee.SteelAxe"/>
<!   abstract      bean    bean-->
<bean id="chineseTemplate" class="lee.Chinese" abstract="true">
<!--           〉
<property name="axe">
<ref local="steelAxe"/>
</property>
</bean>
<!   parent      bean ?
<bean id="chinese" parent="chineseTemplate"/>
</beans>
サブbeanと普通のbeanの定義はあまり違いません。parent属性を追加しただけです。子beanはクラス属性がなくてもいいです。親bean定義にクラス属性があれば、子bean定義にそのクラス属性は省略できますが、子beanは親beanと同じ実現クラスを採用します。
試験手順の変更は以下の通りです。

public class BeanTest
{
public static void main(String[] args)throws Exception{
ApplicationContext ctx = new FileSysternXmlApplicationContext("bean.xml");
Person p = (Person)ctx.getBean("chinese");
p.useAxe();
}
}
プログラム実行結果は以下の通りです。
Spring实例化依存bean:Steee 1 Axe例.
Springの実例.
spring実行依存関係注入…
斧はまきを切るのが速い
また、子beanは親bean定義からクラスを継承し、beanに依存している。しかし、サブbeanは親beanの定義をカバーすることもできます。以下のような配置ファイルを参照してください。

//Axe     StoneAxe  :
public class StoneAxe implements Axe
//     
public StoneAxe(){
System.out.println("Spring     bean: StoneAxe  .. .");
}
//  Axe    chop   
public String chop(){
return "      ";
}
}
Chineseサブクラスは以下の通りです。

public class Shanghai extends Chinese {

  public void show() {
        System.out.println(" Bean ,     ");
  }

}

<?xm1 version="1.0" encoding="gb2312"?>
<!   Spring      dtd>
<lDOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
''http://www.springframework.org/dtd/spring-beans.dtd''>
<! -- Spring          〉
<beans>
<bean id="steelAxe" class="lee.SteelAxe"/>
<bean id="stoneAxe" class="lee.StoneAxe"/>
<!   abstract      bean    bean-->
<bean id="chineseTemplate" class="lee.Chinese" abstract="true">
<property name="axe">
<ref local="steelAxe"/>
</property>
</bean>
<!   parent      bean-->
<bean id="shanghai" parent="chineseTemplate">
<!    bean      …〉
<property name="axe">
<ref local="stoneAxe"/>
</property>
</bean>
</beans>
この時、サブbeanの依存はもはや親の定義の依存ではない。この時の父親類lee.Chineseは抽象類ではなく、必ずしもこの類は抽象類であるとは限りません。抽象類ではなく、Springで抽象的なBeanと定義できます。もしあなたのクラスが抽象類であれば、この時は親Beanのクラスを使ってはいけません。必ずBeanでClassを定義して初期化してください。
試験手順の変更は以下の通りです。

public class BeanTest
{
public static void main(String[] args)throws Exception{
ApplicationContext ctx = new FileSysternXmlApplicationContext("bean.xml");
Person p = (Person)ctx.getBean("shanghai");
p.useAxe();
}
}
上記のテスト手順で実行した結果は以下の通りです。
Spring实例化依存bean:Steel Axe例.
spring实例化依存bean:StneAxe例.
Springの実例.
Spring実行依存関係注入…
石斧のまき割りは遅い
上記の例のサブbean定義にはクラス属性がないので、親bean定義にはクラス属性があります。サブbeanのクラス属性は親bean定義から継承できますが、注意したいのは親Beanからクラスを引き継ぐ時、親Beanは抽象類ではないです。抽象類はインスタンスを作成できないからです。親bean定義にクラス属性が指定されていない場合、子bean定義にはクラス属性が指定されている必要があります。そうでないとエラーが発生します。親beanがclass属性を指定し、子beanもclass属性を指定すると、子beanは定義されたclass属性を親beanが定義するclass属性に上書きします。
Springにおけるbeanの継承はJavaにおける継承とは異なり、前者はインスタンスとインスタンスの間のパラメータの継続であり、後者は一般的に特殊な微細化であり、前者はオブジェクトとオブジェクトの関係であり、後者はクラスとクラスの関係である。
  a.Springの中の子beanと父beanは異なるタイプであってもいいですが、Javaの中の継承は、子類は特別な父類です。
  b.Springにおけるbeanの継承は実例間の関係であり、主にパラメータの継続を表し、Javaにおける継承はクラスとクラスの関係であり、主に方法と属性の継続を表している。
  c.Spring中性子beanは親beanとして使用できません。多形性を備えていません。Javaにおけるサブクラスのインスタンスは親の実例として完全に使用できます。
締め括りをつける
本文はSpringのbeanの継承と抽象コードの例についての内容はここまでです。興味のある友達はこの駅の他のテーマを参照してください。皆さん、当駅を応援してくれてありがとうございます。