SpringコアBean工場組立_u u 0026 quot;Spring学習ノート


Springで最もコアなコンポーネントはbean工場であり、基本的な逆制御と注入依存の能力を提供している.Springは侵入性のない枠組みであり、bean工場に管理されているコンポーネントはspringの存在を知る必要がない.bean工場はbeanを製造し、それらの間の依存を注射します.これらのbeanはお互いに協力します.springの中で最も基本的なBenFactoryインターフェースorg.springframe ebook.beans.factory.BenFactoryは、いくつかの工場の基本的な方法を提供します.
package org.springframework.beans.factory;
import org.springframework.beans.BeansFaException;

public interface BeanFacotory
{
      //      bean
      Object getBean(String name) throws BeansException;
      //    bean         
      Object getBean(String name,Class requiredType);
      
      boolean containsBean(String name);
      //    bean    singleton     ,          。              
      boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
      Class getType(String name) throws NoSuchBeanDefinitionException;
      String getAliases(String name) throws NoSuchBeanDefinitionException;
}

 
ベスン工場を具体化する3つの方法:
 
package com.cao.spring;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.io.Resource;
import org.springframework.beans.factory.xml.XmlBeanFactory;
public class BeanFactoryUsage ...{
    public static void main(String[] args)...{
        //          BeanFactory;
        //              。(    /com/cao/    )
        org.springframework.core.io.Resource res = new org.springframework.core.io.FileSystemResource("com/cao/bean.xml");
        org.springframework.beans.factory.BeanFactory factory = new org.springframework.beans.factory.xml.XmlBeanFactory(res);
        
        System.out.println("OK"+factory);
        
        
        // classpath       BeanFactory (Eclipse    src/data   )
        org.springframework.core.io.Resource  resClasspath = new org.springframework.core.io.ClassPathResource("data/bean2.xml");
        org.springframework.beans.factory.BeanFactory factory2 = new XmlBeanFactory(resClasspath);
        
        //  ApplicationContext    classpath  xml      BeanFacotory
        String classPath = "data/";
        org.springframework.context.ApplicationContext appContext = new org.springframework.context.support.ClassPathXmlApplicationContext(new String[]...{classPath+"bean2.xml"});
        //          。
        org.springframework.beans.factory.BeanFactory factory3 = (BeanFactory)appContext;
    
    }

}
 
 Bean工場の処理過程(1)Springでは、BenDefinitionインターフェースとして抽象的に定義されています.XMLBenFactoryまたはClass PathXml Application Contextの都度、AbstractBenDefinitionを形成してBenFactoryに登録します.(2)このプロセスでは、いくつかのBenFactoryは、プレ初期化(Class PathXml ApplitonitonContatxtなど)を行うことができます.これにより、顧客コードは、getBenを呼び出したときに、速やかにBeanのインスタンスを取得することができます.
静的工場法を使ってビーンを作成します.
静的工場法によりビーンを作成し,ファクトリー-method属性を用いて工場法名を指定した.目標のbeanのクラスの属性はどの静的工場を含むクラスですか?bean id=「legacyBean」class=「comp.LegacySingleton」factory-method=「get Instance」このbean配置は、返却対象のタイプを指定しておらず、工場法を含むクラスを指定しているだけです.また、このようなget Instance方法は、静的な方法でなければならない.
実例工場法を使ってビーンを作成する
具体的な工場法を通じてビーンを作成します.静的な工場を使用して、知られているビーンの工場方法を呼び出して、新しいビーンを作成します.factory-beanマッピングid="legacyBean"  factory-methodはbeanを生産する方法を指定しています.
Springでは、Ioc/DIは主に2つのタイプがあります.(1)設定値法の依存注入に基づいて,beanのsetter法により実現した.構築方法または他の方法でbeanを作成した場合には、進入setter注入も完全に許可されます.(2)構造法による依存注入は、複数のパラメータを有する構造を呼び出して実現される.これらのパラメータは、beanの協力者(注入する例)または属性を表しています.springは、特定のパラメータの静的工場法により、beanを構成することもまた、このようなものとする.
 
1,setterの依存に基づくbeanの配置
 
<bean id="setterBean" class="com.cao.SetterBean" >
   <property name="beanOne"> 
       <ref bean="anotherBean"/>  
   </property> 
   <property name="beanTwo"> 
        <ref bean="yetAntherBean"/>
    </property>
    <property name="integerProperty">
           <value>1<value>
    </property>
</bean>
<bean id="anotherBean" class="com.cao.AnotherBean" />
<bean id="yetAntherBean" class="com.cao.YetAnotherBean" />

 
//    。
package com.cao.spring;

public class SetterBean ...{
    private AnotherBean beanOne;
    private YetAnotherBean beanTwo;
    private int i;
    
    
    
    public void setBeanOne(AnotherBean beanOne) ...{
        this.beanOne = beanOne;
    }

    public void setIntegerProperty(int i) ...{
        this.i = i;
    }

    

    public void setBeanTwo(YetAnotherBean beanTwo) ...{
        this.beanTwo = beanTwo;
    }

    @Override
    public String toString() ...{
        // TODO Auto-generated method stub
        return "beanOne"+this.beanOne+":beanTwo" +this.beanTwo+":int"+this.i;
    }
    
    
    public static void main(String[] args)...{
        org.springframework.core.io.Resource rs = new org.springframework.core.io.ClassPathResource("data/setter.xml");
        org.springframework.beans.factory.BeanFactory factory= 
             new org.springframework.beans.factory.xml.XmlBeanFactory(rs);
        
        System.out.println(factory.getBean("setterBean"));
    }
    
}
 
クラスとプロファイルを比較して見られます.property name=「beanOne」  のname対応クラスの一つのsetXXXメソッドxxxとnameの値はjavaBeanの定義を満たす.                             実際には、comp.ca.AnotherBeanというクラスをsetXXXの方法で、クラスのcomp.ca.SetterBenのメンバーとして設定しています.
2,構造方法によるDI配置
<beans>
    <bean id="constructBean" class="com.cao.spring.ConstructBean">
        <constructor-arg>
            <ref bean="beanOne"/>
        </constructor-arg>
        <constructor-arg>
            <ref bean="beanTwo"/>
        </constructor-arg>
        
        <constructor-arg index="2">
            <value type="int">1</value>
        </constructor-arg>
    </bean>
    
    <bean id="beanOne" class="com.cao.spring.AnotherBean"/>
    <bean id="beanTwo" class="com.cao.spring.YetAnotherBean"/>
</beans>
 
//   
package com.cao.spring;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class ConstructBean ...{
    private AnotherBean beanOne;
    private YetAnotherBean beanTwo;
    private int i;
    public ConstructBean(AnotherBean beanOne, YetAnotherBean beanTwo, int i) ...{
        super();
        this.beanOne = beanOne;
        this.beanTwo = beanTwo;
        this.i = i;
    }
    public String toString() ...{
        // TODO Auto-generated method stub
        return "beanOne"+this.beanOne+":beanTwo" +this.beanTwo+":int"+this.i;
    }
    
    public static void main(String[] args)...{
        Resource rs = new ClassPathResource("data/construct.xml");
        BeanFactory factory = new XmlBeanFactory(rs);
        System.out.println(factory.getBean("constructBean"));
        
    }
}

  
テストをしたところ、<constructor-arg>構成におけるパラメータの順序は、必ずしも構造方法のパラメータの順序と同じではないことが分かりました.index="2"でパラメータの位置を指定します(0から開始します)
3,構造方法によるDI配置_u u工場の呼び出し方法(静的または非静的)
 
<beans>
    <bean id="diFactory" class="com.cao.spring.DIFactory"/>
          <!--          factory-bean            。factory-method       -->
    <bean id="product" factory-bean="diFactory" factory-method="make">
        <constructor-arg>
            <ref bean="beanOne"/>
        </constructor-arg>
        <constructor-arg>
            <ref bean="beanTwo"/>
        </constructor-arg>
        <constructor-arg>
            <value>1</value>
        </constructor-arg>
    </bean>    
    
    <bean id="beanOne" class="com.cao.spring.AnotherBean"/>
    <bean id="beanTwo" class="com.cao.spring.YetAnotherBean"/>
    <!--       factory-method       (  )               -->
    <bean id="productStatic" class="com.cao.spring.DIFactory" factory-method="create">
        <constructor-arg>
            <ref bean="beanOne"/>
        </constructor-arg>
        <constructor-arg>
            <ref bean="beanTwo"/>
        </constructor-arg>
        <constructor-arg>
            <value>1</value>
        </constructor-arg>
    </bean>
</beans>

 
 
Spring自動組立(atowiring)1,no     自動組立は行われません.これはスプリングの標準構成です.2,byNameは属性名により自動組立を行う.Springは組み立てるべきbean属性の同名のbeanを検索します.(テスト:マッチングが見つからない場合は、そのデフォルト値null/0参照タイプはnull、基本データタイプは0)3、byType Springは、組み立てるべきbeanと同じタイプのbeanを検索しますが、一つ以上のbeanを見つけたら、例外が出ます.(テスト:同じbeanでも対応が違っているidは間違えます.足りなければエラーなく空欄です.dependency-check=「object」が足りなければエラーが発生します.)4、constructtorはbyTypeに似ています.属性ではなく構成子パラメータにマッチします.5,autdetect  springに自動的にconstrutorまたはbyTypeを選択させるデフォルトの構造方法を見つけたらbyTypeを使用します.
依存チェック:モード:   説明none     依存チェックを行いません.   基本タイプと集合に対して依存検査を行う.   協力者(どのタイプを注入しますか?)に依存してallをチェックします.      協力者に対して、基本的なタイプと集合を検査します.
コレクション要素を使用してセットを定義する.
 
<beans>
    <bean id="complext" class="com.cao.spring.ComplexBean">
                 <!--java.util.Properties-->
        <property name="people">
            <props>
                <prop key="name">Spirti.J</prop>
                <prop key="age">25</prop>
            </props>
        </property>
        
        <property name="comeList">
            <list>
                <!--       <value>         spring      -->
                <value>list       ,        bean   </value>
                <ref bean="anotherBean"/>
            </list>
        </property>
        
        <property name="someMap">
            <map>
                <!--   :      key             -->
                <entry key="key-String" value="      "/>
                <entry>
                    <key><value>key-String</value></key>
                    <value>      </value>
                </entry>
                
                <!--          -->
                <entry key="key-ref" value-ref="anotherBean"></entry>
                
                <entry>
                    <key><value>key-ref</value></key>
                    <!-- ref               <value>          -->
                    <ref bean="anotherBean"/>    
                </entry>
            </map>
        </property>
        
        <property name="someSet">
            <set>
                <!--   : set      ,          -->
                <value>      </value>
                <ref bean="anotherBean"/>
            </set>
            
        </property>
        
    </bean>
    <bean id="anotherBean" class="com.cao.spring.AnotherBean"/>
</beans>
 
内部のbean内部のbeanを入れ子beanによって定義するためには、IDまたはsingletonタグは不要であり、匿名の内部の原形であり、その例は外部の部類にのみ使用される.
 
<bean id="outerBean" class="com.cao.spring.OuterBean">
        <property name="target">
            <!--   bean    id .  :      .     -->
            <bean  class="com.cao.spring.ComplexBean">
                <property name="people">
                    <props>
                        <prop key="name">Spirit.J</prop>
                        <prop key="age">25</prop>
                    </props>
                </property>
                         </bean>
        </property>

</bean>
 
方法注入はなぜ方法注入が必要ですか?一つのsingleton beanAと一つのnon-singleton beanBを仮定すると、容器はbeanAに対して一度だけ実用化されます.一回だけその属性を設定する機会があります.したがって、毎回beanAのために新しいbeanBの実例を提供することができません.beanBはBeanAの属性ですから.
lookupメソッドを使用して注入し、lookup方法は、実行時にbeanの抽象的または具体的な方法を書き換えて、容器内の他のbeanの例を返したり、作成したりすることができます.作成されたのは一般的にnon-singleton beanですが、singletonでもいいです.(springはCGLOIBによる注入)
 
<beans>
    <bean id="anotherBean" class="com.cao.spring.AnotherBean" singleton="false"/>
    <bean id="myBean" class="com.cao.spring.MyLookUpBean">
        <lookup-method name="newAnotherBean" bean="anotherBean"/>
    </bean>
</beans>
 
MyLook UpBenの中に方法protected AnotherBen newAnotherBen()があります.  return null }MyLook UpBenでこの方法を呼び出すと、springはこの方法を書き換えてAnotherBenの例を返します.
任意の方法を置き換える.存在する方法でreplace-method要素を置き換えることによって実現されます.メソッドを使用して、実現するインターフェースorg.springfarmework.beans.factory.support.MethodReplacerインターフェースを置換します.
 
<bean id="myReplaceBean" class="com.cao.spring.MyValueCalculator">
        <replaced-method name="computeValue" replacer="aaa">
            <arg-type>String</arg-type>
            
        </replaced-method>
    </bean>
    <bean id="aaa" class="com.cao.spring.ReplacementComputeValue"/>
 元々MyValue Calculator類には一つの方法があります.public String comput Value(String input){  System.out.println(「元の計算」)  return"; }
結果として、運転時にはReplaccement Computation Valueクラスでの実装に置き換えられます.改種はMethodReplacerインターフェースを実現しました.このインターフェースのreimplementメソッドをカバーすることで、computeValueとして実装されます.
Beanのオリジナル属性Springは、InitializingBeanとDispsable Beanを含むいくつかのライフサイクルのマークインターフェースを提供しています.彼らはbeanの挙動を変えることができます.Beanが初期化と解析の時に特定の処理を実行するようにします.方法の一つのbeanはInitializingBenインターフェースを実現し、この方法を使用して初期化作業を完了することができます.しかし、このようにすると、beanとspringフレームが結合します.より良い方法は、プロファイルの中でinit-method属性を指定することによって、初期化作業を完了します.Dispposable Bernとdestroy-method属性を使用します.法類似初期化
ビーンはまず属性の注入を完了し、工場が破壊された時に初期化します.その後、シングルンビーンを破壊した場合、何度もfactory.getBen(「someBean」)を破壊します.これらの仕事は属性を含む注入を一回だけ行います.
 
<bean id="someBean" class="com.cao.spring.SomeBean" init-method="afterPropertiesSetOfMy" destroy-method="destroyOfMy">
 ビーン自身の関連情報を取得するBenNameAwareインターフェースSpring容器は、このインターフェースを通じてビーンを呼び出して関連情報を取得します.取得するタイミングは注入属性の後、イニシャル方法の前になります.
public class AwareBean implements org.springframework.beans.factory.BeanNameAware,org.springframework.beans.factory.BeanFactoryAware ...{

    private String beanName;
    private BeanFactory factory;
    
    public void setBeanName(String arg0) ...{
         this.beanName = arg0;    
    }
    
    public void setBeanFactory(BeanFactory arg0) throws BeansException ...{
        this.factory = arg0;
    }
    
    public void doInit()...{
        String name= factory.getClass().getName();
        
        System.out.println("  "+name+"   "+beanName);
    }
    public static void main(String[] args)...{
        org.springframework.core.io.Resource rs  = 
             new ClassPathResource("data/beanAware.xml");
        
        org.springframework.beans.factory.BeanFactory factory = 
            new XmlBeanFactory(rs);
        
        factory.getBean("beanAware");
    }
}

 
コードを解析すると、ビーンがそのクリエイターから引用を受けることができるということが分かります.この引用を利用して、より多くの情報を得ることができます.また、このビーンファクトリーを適切な工場タイプに強制的に変換して、より多くの情報を得ることができます.
親子beanの定義は、1つのbeanの定義に多くの構成情報が含まれ、1つのサブbeanの定義は、親beanの構成を継承することができます.他の情報をカバーして追加することができます.Springでは、親beanをワードbeanのテンプレートとすることができます.親子beanを使用すると、多くの重複した仕事を減らすことができます.サブbeanは、parent属性を使用して、親beanを指すことができます.
 
 <bean id="father" class="com.cao.spring.ParentBean">
        <property name="name" value="parent"/>
        <property name="age" value="20"/>
    </bean>
                                                       <!-- parent     bean -->
    <bean id="child" class="com.cao.spring.ChildBean" parent="father">
        <!--    baen  name      -->
        <property name="name" value="override"/>
        </bean>

 
1>PartaBen father=(ChildBen)factory.getBen("child")     2>PartaBen father=(PartBean)factory.getBen("child")    father.get Name()、得られたのはすべてoverride説明factory工場が創建した本当の例ですか?それともChildBenがid=「Child」のbeanがclass属性がない場合は2>方法でモデルチェンジして得られる本当の例は依然としてChildBenです.
容器は無視してクラスもparent属性もないbeanがあります.
後理器を使います.ビーンpost-processorはBenPostProcessorインターフェースを実現する必要があります.二つの方法があります.postProcess Before Initialzation()とpostProcess After Initiazation()があります.;ベース工場にpost-processorが登録されていると、作成された各beanのインスタンスに対して、初期化方法の前後にフィードバックが得られます.テストで発見されました.ビーンFactoryを使って組み立てるときは、プロファイルに後処理クラスをマッピングする必要はありません.自動的に呼び出しられます.ただし、手動で登録します.        org.springframe ewk.beans.factory.co.fig.C.onfigrable BenFactory config=new Xml BenFactor(rs);           org.springframe ewk.beans.factory.com fig.BenPostProcessor=new MyBenPostProcessor();   config.addBenPostProcessor;
          Application Contect工場を使って自動組立する場合は、配置ファイルにこのクラスをマッピングする必要があります.          あなたのプロフィールにMyBeanPostProcessorという種類があります.idは自由に取ってもいいようです.
BenFactory PostProcessorを使ってBenFacotoryPostProcessorを実現するクラスはBen factory post-processorであり、bean工場の創建後にbean全体に対して何らかの修正ができます.
PropertyPlaceholderConfigrerはSpringプロファイルのプロパティを一つの別々のjava Proptiesファイルから引き出すために使用します.このようにSpringでの配置変更は避けられます.