<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    空間站

    北極心空

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks

    BeanFactory&ApplicationContext--part1

    3.1. 簡介

    在Spring中,兩個最基本最重要的包是 org.springframework.beansorg.springframework.context. 這兩個包中的代碼為Spring的反向控制 特性(也叫作依賴注射)提供了基礎。 BeanFactory提供了一種先進的配置機制來管理任何種類bean(對象),這種配置機制考慮到任何一種可能的存儲方式。 ApplicationContext建立在BeanFactory之上,并增加了其他的功能,比如更容易同Spring AOP特性整合, 消息資源處理(用于國際化),事件傳遞,以聲明的方式創建ApplicationContext, 可選的父上下文和與應用層相關的上下文(比如WebApplicationContext),以及其他方面的增強。

    簡而言之,BeanFactory提供了配置框架和基本的功能, 而 ApplicationContext為它增加了更強的功能,這些功能中的一些或許更加接近J2EE并且圍繞企業級應用。一般來說,ApplicationContext是BeanFactory的完全超集, 任何BeanFactory功能和行為的描述也同樣被認為適用于ApplicationContext

    用戶有時不能確定BeanFactory和ApplicationContext中哪一個在特定場合下更適合。 通常大部分在J2EE環境的應用中,最好選擇使用ApplicationContext, 因為它不僅提供了BeanFactory所有的特性以及它自己附加的特性,而且還提供以聲明的方式使用一些功能, 這通常是令人滿意的。BeanFactory主要是在非常關注內存使用的情況下 (比如在一個每kb都要計算的applet中)使用,而且你也不需要用到ApplicationContext的所有特性。

    這一章粗略地分為兩部分,第一部分包括對BeanFactory和ApplicationContext都適用的一些基本原則。第二部分包括僅僅適用于ApplicationContext的一些特性

    3.2. BeanFactory 和 BeanDefinitions - 基礎

    3.2.1. BeanFactory

    BeanFactory實際上是實例化,配置和管理眾多bean的容器。 這些bean通常會彼此合作,因而它們之間會產生依賴。 BeanFactory使用的配置數據可以反映這些依賴關系中 (一些依賴可能不像配置數據一樣可見,而是在運行期作為bean之間程序交互的函數)。

    一個BeanFactory可以用接口org.springframework.beans.factory.BeanFactory表示, 這個接口有多個實現。 最常使用的的簡單的eanFactory實現是org.springframework.beans.factory.xml.XmlBeanFactory。 (這里提醒一下:ApplicationContext是BeanFactory的子類, 所以大多數的用戶更喜歡使用ApplicationContext的XML形式)。

    雖然大多數情況下,幾乎所有被BeanFactory管理的用戶代碼都不需要知道BeanFactory, 但是BeanFactory還是以某種方式實例化。可以使用下面的代碼實例化BeanFactory:

    InputStream is = new FileInputStream("beans.xml");
    XmlBeanFactory factory = new XmlBeanFactory(is);

    或者

    ClassPathResource res = new ClassPathResource("beans.xml");
    XmlBeanFactory factory = new XmlBeanFactory(res);

    或者

    ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
    new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
    // of course, an ApplicationContext is just a BeanFactory
    BeanFactory factory = (BeanFactory) appContext;

    很多情況下,用戶代碼不需要實例化BeanFactory, 因為Spring框架代碼會做這件事。例如,web層提供支持代碼,在J2EE web應用啟動過程中自動載入一個Spring ApplicationContext。這個聲明過程在這里描述:

    編程操作BeanFactory將會在后面提到,下面部分將集中描述BeanFactory的配置.

    一個最基本的BeanFactory配置由一個或多個它所管理的Bean定義組成。在一個XmlBeanFactory中,根節點beans中包含一個或多個bean元素。

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
    <bean  >
    ...
    </bean>
    <bean  >
    ...
    </bean>
    ...
    </beans>

    3.2.2. BeanDefinition

    一個XmlBeanFactory中的Bean定義包括的內容有:

    • classname:這通常是bean的真正的實現類。但是如果一個bean使用一個靜態工廠方法所創建而不是被普通的構造函數創建,那么這實際上就是工廠類的classname

    • bean行為配置元素:它聲明這個bean在容器的行為方式(比如prototype或singleton,自動裝配模式,依賴檢查模式,初始化和析構方法)

    • 構造函數的參數和新創建bean需要的屬性:舉一個例子,一個管理連接池的bean使用的連接數目(即可以指定為一個屬性,也可以作為一個構造函數參數),或者池的大小限制

    • 和這個bean工作相關的其他bean:比如它的合作者(同樣可以作為屬性或者構造函數的參數)。這個也被叫做依賴。

    上面列出的概念直接轉化為組成bean定義的一組元素。這些元素在下面的表格中列出,它們每一個都有更詳細的說明的鏈接。

    注意bean定義可以表示為真正的接口org.springframework.beans.factory.config.BeanDefinition以及它的各種子接口和實現。然而,絕大多數的用戶代碼不需要與BeanDefination直接接觸。

    3.2.3. bean的類

    class屬性通常是強制性的(參考第 3.2.3.3 節 “通過實例工廠方法創建bean”第 3.5 節 “子bean定義”),有兩種用法。在絕大多數情況下,BeanFactory直接調用bean的構造函數來"new"一個bean(相當于調用new的Java代碼),class屬性指定了需要創建的bean的類。 在比較少的情況下,BeanFactory調用某個類的靜態的工廠方法來創建bean, class屬性指定了實際包含靜態工廠方法的那個類。 (至于靜態工廠方法返回的bean的類型是同一個類還是完全不同的另一個類,這并不重要)。

    3.2.3.1. 通過構造函數創建beanbean /> <bean />
    
    

    至于為構造函數提供(可選的)參數,以及對象實例創建后設置實例屬性,將會在后面敘述

    3.2.3.2. 通過靜態工廠方法創建Bean

    當你定義一個使用靜態工廠方法創建的bean,同時使用class屬性指定包含靜態工廠方法的類,這個時候需要factory-method屬性來指定工廠方法名。Spring調用這個方法(包含一組可選的參數)并返回一個有效的對象,之后這個對象就完全和構造方法創建的對象一樣。用戶可以使用這樣的bean定義在遺留代碼中調用靜態工廠。

    下面是一個bean定義的例子,聲明這個bean要通過factory-method指定的方法創建。注意這個bean定義并沒有指定返回對象的類型,只指定包含工廠方法的類。在這個例子中,createInstance 必須是static方法 .

    <bean
    factory-method="createInstance"/>

    至于為工廠方法提供(可選的)參數,以及對象實例被工廠方法創建后設置實例屬性,將會在后面敘述.

    3.2.3.3. 通過實例工廠方法創建bean

    使用一個實例工廠方法(非靜態的)創建bean和使用靜態工廠方法非常類似,調用一個已存在的bean(這個bean應該是工廠類型)的工廠方法來創建新的bean。

    使用這種機制,class屬性必須為空,而且factory-bean屬性必須指定一個bean的名字,這個bean一定要在當前的bean工廠或者父bean工廠中,并包含工廠方法。 而工廠方法本身仍然要通過factory-method屬性設置。

    下面是一個例子:

    <!-- The factory bean, which contains a method called
    createInstance -->
    <bean
    >
    ...
    </bean>
    <!-- The bean to be created via the factory bean -->
    <bean
    factory-bean="myFactoryBean"
    factory-method="createInstance"/>

    雖然我們要在后面討論設置bean的屬性,但是這個方法意味著工廠bean本身能夠被容器通過依賴注射來管理和配置

    3.2.4. Bean的標志符 (idname)

    每一個bean都有一個或多個id(也叫作標志符,或名字;這些名詞說的是一回事)。這些id在管理bean的BeanFactory或ApplicationContext中必須是唯一的。 一個bean差不多總是只有一個id,但是如果一個bean有超過一個的id,那么另外的那些本質上可以認為是別名。

    在一個XmlBeanFactory中(包括ApplicationContext的形式), 你可以用id或者name屬性來指定bean的id(s),并且在這兩個或其中一個屬性中至少指定一個id。 id屬性允許你指定一個id,并且它在XML DTD(定義文檔)中作為一個真正的XML元素的ID屬性被標記, 所以XML解析器能夠在其他元素指回向它的時候做一些額外的校驗。正因如此,用id屬性指定bean的id是一個比較好的方式。 然而,XML規范嚴格限定了在XML ID中合法的字符。通常這并不是真正限制你, 但是如果你有必要使用這些字符(在ID中的非法字符),或者你想給bean增加其他的別名, 那么你可以通過name屬性指定一個或多個id(用逗號,或者分號;分隔)。

    3.2.5. Singleton的使用與否

    Beans被定義為兩種部署模式中的一種:singleton或non-singleton。 (后一種也別叫作prototype,盡管這個名詞用的不精確因為它并不是非常適合)。 如果一個bean是singleton形態的,那么就只有一個共享的實例存在, 所有和這個bean定義的id符合的bean請求都會返回這個唯一的、特定的實例。

    如果bean以non-singleton,prototype模式部署的話,對這個bean的每次請求都會創建一個新的bean實例。這對于例如每個user需要一個獨立的user對象這樣的情況是非常理想的。

    Beans默認被部署為singleton模式,除非你指定。要記住把部署模式變為non-singletion(prototype)后,每一次對這個bean的請求都會導致一個新創建的bean,而這可能并不是你真正想要的。所以僅僅在絕對需要的時候才把模式改成prototype。

    在下面這個例子中,兩個bean一個被定義為singleton,而另一個被定義為non-singleton(prototype)。客戶端每次向BeanFactory請求都會創建新的exampleBean,而AnotherExample僅僅被創建一次;在每次對它請求都會返回這個實例的引用。

    <bean
    singleton="false"/>
    <bean
    singleton="true"/>

    注意:當部署一個bean為prototype模式,這個bean的生命周期就會有稍許改變。 通過定義,Spring無法管理一個non-singleton/prototype bean的整個生命周期, 因為當它創建之后,它被交給客戶端而且容器根本不再跟蹤它了。當說起non-singleton/prototype bean的時候, 你可以把Spring的角色想象成“new”操作符的替代品。從那之后的任何生命周期方面的事情都由客戶端來處理 。BeanFactory中bean的生命周期將會在 第 3.4.1 節 “生命周期接口”一節中有更詳細的敘述。

    3.3. 屬性,合作者,自動裝配和依賴檢查

    3.3.1. 設置bean的屬性和合作者

    反向控制通常與依賴注入同時提及。基本的規則是bean通過以下方式來定義它們的依賴(比如它們與之合作的其他對象):構造函數的參數,工廠方法的參數;當對象實例被構造出來或從一個工廠方法返回后設置在這個實例上的屬性。容器的工作就是創建完bean之后,真正地注入這些依賴。這完全是和一般控制方式相反的(因此稱為反向控制),比如bean實例化,或者直接使用構造函數定位依賴關系,或者類似Service Locator模式的東西。我們不會詳細闡述依賴注射的優點,很顯然通過使用它:代碼變得非常清晰;當bean不再自己查找他們依賴的類而是由容器提供,甚至不需要知道這些類在哪里以及它們實際上是什么類型,這時高層次的解耦也變得很容易了。

    正如上面提到的那樣,反向控制/依賴注射存在兩種主要的形式:

    • 基于setter的依賴注射,是在調用無參的構造函數或無參的靜態工廠方法實例化你的bean之后, 通過調用你的bean上的setter方法實現的。 在BeanFactory中定義的使用基于setter方法的注射依賴的bean是真正的JavaBean。 Spring一般提倡使用基于setter方法的依賴注射,因為很多的構造函數參數將會是笨重的, 尤其在有些屬性是可選的情況下。

    • 基于構造函數的依賴注射,它是通過調用帶有許多參數的構造方法實現的, 每個參數表示一個合作者或者屬性。 另外,調用帶有特定參數的靜態工廠方法來構造bean可以被認為差不多等同的, 接下來的文字會把構造函數的參數看成和靜態工廠方法的參數類似。 雖然Spring一般提倡在大多數情況下使用基于setter的依賴注射, 但是Spring還是完全支持基于構造函數的依賴注射, 因為你可能想要在那些只提供多參數構造函數并且沒有setter方法的遺留的bean上使用Spring。 另外對于一些比較簡單的bean,一些人更喜歡使用構造函數方法以確保bean不會處于錯誤的狀態。

    BeanFactory同時支持這兩種方式將依賴注射到被管理bean中。(實際上它還支持在一些依賴已經通過構造函數方法注射后再使用setter方法注射依賴)。依賴的配置是以BeanDefinition的形式出現,它和JavaBeans的PropertyEditors一起使用從而知道如何把屬性從一個格式轉變為另一個。真正傳送的值被封裝為PropertyValue對象。然而,大多數Spring的使用者并不要直接(比如編程的方式)處理這些類,而更多地使用一個XML定義文件,這個文件會在內部被轉變為這些類的實例,用來讀取整個BeanFactory或ApplicationContext。

    Bean依賴的決定通常取決于下面這些內容:

    1. BeanFactory通過使用一個描述所有bean的配置被創建和實例化。大多數的Spring用戶使用一個支持XML格式配置文件的BeanFactory或ApplicationContext實現。

    2. 每一個bean的依賴表現為屬性,構造函數參數,或者當用靜態工廠方法代替普通構造函數時工廠方法的參數。這些依賴將會在bean真正被創建出來后提供給bean。

    3. 每一個屬性或者構造函數參數要么是一個要被設置的值的定義,要么是一個指向BeanFactory中其他bean的引用。在ApplicationContext的情況下,這個引用可以指向一個父親ApplicationContext中bean。

    4. 每一個屬性或構造函數參數的值,必須能夠從(配置文件中)被指定的格式轉變為真實類型。缺省情況下,Spring能夠把一個字符串格式的值轉變為所有內建的類型,比如int, longString, boolean等等。另外當說到基于XML的BeanFactory實現的時候(包括ApplicationContext實現),它們已經為定義Lists, Maps, Sets和Properties集合類型提供了內在的支持。另外,Spring通過使用JavaBeans的 PropertyEditor定義,能夠將字符串值轉變為其他任意的類型。(你可以為PropertyEditor提供你自己的PropertyEditor定義從而能夠轉變你自定義的類型;更多關于PropertyEditors的信息以及如何手工增加自定義的PropertyEditors請參看第 3.9 節bean > <property ><ref bean="anotherExampleBean"/></property> <property ><ref bean="yetAnotherBean"/></property> <property ><value>1</value></property> </bean> <bean /> <bean />

      
          
          

       

       

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

      正如你所看到的一樣,setter方法被聲明以符合XML文件中指定的屬性。(XML文件中的屬性,直接對應著RootBeanDefinition中的PropertyValues對象)

      接著是一個使用IoC type3(基于構造函數的依賴注射)的BeanFactory。下面是XML配置中的一段,指定了構造函數參數以及展示構造函數的代碼:

      <bean  >
          <constructor-arg><ref bean="anotherExampleBean"/></constructor-arg>
          <constructor-arg><ref bean="yetAnotherBean"/></constructor-arg>
          <constructor-arg><value>1</value></constructor-arg>
          </bean>
          <bean  />
          <bean  />

       

      public class ExampleBean {
          private AnotherBean beanOne;
          private YetAnotherBean beanTwo;
          private int i;
          public ExampleBean(AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {
          this.beanOne = anotherBean;
          this.beanTwo = yetAnotherBean;
          this.i = i;bean
          factory-method="createInstance">
          <constructor-arg><ref bean="anotherExampleBean"/></constructor-arg>
          <constructor-arg><ref bean="yetAnotherBean"/></constructor-arg>
          <constructor-arg><value>1</value></constructor-arg>
          </bean>
          <bean  />
          <bean  />

       

      public class ExampleBean {
          ...
          // a private constructor
          private ExampleBean(...) {
          ...
          }
          // a static factory method
          // the arguments to this method can be considered the dependencies of the bean that
          // is returned, regardless of how those arguments are actually used.
          public static ExampleBean ExampleBean(AnotherBean anotherBean,
          YetAnotherBean yetAnotherBean, int i) {
          ExampleBean eb = new ExampleBean(...);
          // some other operations
          ...
          return eb;
          }
          }

      需要注意的是:靜態工廠方法的參數由 constructor-arg元素提供,這和構造函數的用法是一樣的。這些參數是可選的。重要的一點是工廠方法所返回的對象類型不一定和包含這個靜態工廠方法的類一致,雖然上面這個例子中是一樣的。前面所提到的實例工廠方法(non-static)用法基本上是一樣的(除了使用factory-bean屬性代替class屬性),在這里就不再詳細敘述了。 .

    3.3.2. 深入Bean屬性和構造函數參數

    正如前面提到的那樣,bean的屬性和構造函數參數可以被定義為其他bean的引用(合作者),或者內聯定義的值。為了達到這個目的,XmlBeanFactory在property和constructor-arg元素中支持許多子元素類型。

    value元素用適合人讀的字符串形式指定屬性或構造函數參數。正如前面提到的那樣,JavaBeans的PropertyEditors被用來將這些字符串從java.lang.String類型轉變為真實的屬性類型或參數類型。

    <beans>
    <bean   destroy-method="close">
    <!-- results in a setDriverClassName(String) call -->
    <property >
    <value>com.mysql.jdbc.Driver</value>
    </property>
    <property >
    <value>jdbc:mysql://localhost:3306/mydb</value>
    </property>
    <property >
    <value>root</value>
    </property>
    </bean>
    </beans>bean >
    <property ><value></value></property>
    </bean>        

    導致email屬性被設置為””,同java代碼:exampleBean.setEmail("")等價。而專門的<null>元素則可以用來指定一個null值,所以

    <bean >
    <property ><null/></property>
    </bean>        

    同代碼:exampleBean.setEmail(null)是等價的.

    list, set, map, 以及 props 元素可以用來定義和設置類型 為Java的List,Set, Map, 和 Properties .

    <beans>
    ...
    <bean  >
    <!-- results in a setPeople(java.util.Properties) call -->
    <property >
    <props>
    <prop key="HarryPotter">The magic property</prop>
    <prop key="JerrySeinfeld">The funny property</prop>
    </props>
    </property>
    <!-- results in a setSomeList(java.util.List) call -->
    <property >
    <list>
    <value>a list element followed by a reference</value>
    <ref bean="myDataSource"/>
    </list>
    </property>
    <!-- results in a setSomeMap(java.util.Map) call -->
    <property >
    <map>
    <entry key="yup an entry">
    <value>just some string</value>
    </entry>
    <entry key="yup a ref">
    <ref bean="myDataSource"/>
    </entry>
    </map>
    </property>
    <!-- results in a setSomeSet(java.util.Set) call -->
    <property >
    <set>
    <value>just some string</value>
    <ref bean="myDataSource"/>
    </set>
    </property>
    </bean>
    </beans>

    注意:Map的entry或set的value,它們的值又可以是下面元素中的任何一個:

    (bean | ref | idref | list | set | map | props | value | null)

    property 元素中定義的bean元素用來定義一個內聯的bean,而不是引用BeanFactory其他地方定義的bean。內聯bean定義不需要任何id定義

    <bean  >
    <!-- Instead of using a reference to target, just use an inner bean -->
    <property >
    <bean >
    <property ><value>Tony</value></property>
    <property ><value>51</value></property>
    </bean>
    </property>
    </bean>

    idref元素完全是一種簡寫和防止錯誤的方式,用來設置屬性值為容器中其他bean的idname

    <bean  >
    </bean>
    <bean  >
    <property >
    <idref bean="theTargetBean"/>
    </property>
    </bean>
    bean > </bean> <bean > <property > <value>theTargetBean</value> </property> </bean>
    
    

    第一種形式比第二種形式更好的原因是:使用idref標記將會使Spring在部署的時候就驗證其他的bean是否真正存在;在第二種形式中,targetName屬性的類僅僅在Spring實例化這個類的時候做它自己的驗證,這很可能在容器真正部署完很久之后。

    另外,如果被引用的bean在同一個xml文件中而且bean的名稱是bean的 id,那么就可以使用local屬性。它會讓XML解析器更早,在XML文檔解析的時候,驗證bean的名稱。

        <property >
    <idref local="theTargetBean"/>
    </property>

    ref元素是最后一個能在property元素中使用的元素。它是用來設置屬性值引用容器管理的其他bean(可以叫做合作者)。正如前一節提到的,擁有這些屬性的bean依賴被引用的bean,被引用的bean將會在屬性設置前,必要的時候需要時初始化(如果是一個singleton bean可能已經被容器初始化)。所有的引用根本上是一個指向其他對象的引用,不過有3種形式指定被引用對象的id/name,這3種不同形式決定作用域和如何處理驗證。

    ref元素的bean屬性指定目標bean是最常見的形式,它允許指向的bean可以在同一個BeanFactory/ApplicationContext(無論是否在同一個XML文件中)中,也可以在父BeanFactory/ApplicationContext中。bean屬性的值可以同目標bean的id屬性相同,也可以同目標bean的name屬性中任何一個值相同。

        <ref bean="someBean"/>

    local屬性指定目標bean可以利用XML解析器的能力在同一個文件中驗證XML id引用。local屬性的值必須與目標bean的id屬性一致。如果在同一個文件中沒有匹配的元素,XML解析器將會產生一個錯誤。因此,如果目標bean在同一個XML文件中,那么使用local形式將是最好的選擇(為了能夠盡可能早的發現錯誤)。

        <ref local="someBean"/>

    parent屬性指定目標bean允許引用當前BeanFactory(ApplicationContext)的父BeanFactory(ApplicationContext)中的bean。parent屬性的值可以同目標bean的id屬性相同,也可以同目標bean的name屬性中的一個值相同,而且目標bean必須在當前BeanFactory(ApplicationContext)的父BeanFactory(ApplicationContext)中。當需要用某種proxy包裝一個父上下文中存在的bean(可能和父上下文中的有同樣的name),所以需要原始的對象用來包裝它。

        <ref parent="someBean"/>

    3.3.3. 方法注入

    對于大部分的用戶來說,容器中多數的bean是singleton的。當一個singleton的bean需要同另一個singleton的 bean合作(使用)時,或者一個非singleton的bean需要同另一個非singleton的bean合作的時候,通過定義一個bean為另一個bean的屬性來處理這種依賴的關系就足夠了。然而當bean的生命周期不同的時候就有一個問題。想想一下一個singleton bean A,或許在每次方法調用的時候都需要使用一個non-singleton bean B。容器僅僅會創建這個singleton bean A一次,因此僅僅有一次的機會去設置它的屬性。因此容器沒有機會每次去為bean A提供新的bean B的實例。

    一個解決這個問題的方法是放棄一些反向控制。Bean A可以通過實現 BeanFactoryAware知道容器的存在(參見來向容器請求新的bean B實例。 因為bean的代碼知道Spring并且耦合于Spring,所以這通常不是一個好的方案。

    方法注入,BeanFactory的高級特性之一,可以以清潔的方式處理這種情況以及其他一些情況。

    3.3.3.1. Lookup方法注入

    
    

    如果方法不是抽象的,Spring就會直接重寫已有的實現。在XmlBeanFactory的情況下,你可以使用bean定義中的lookup-method 屬性來指示Spring去注入/重寫這個方法,以便從容器返回一個特定的bean。舉個例子說明:

    <!-- a stateful bean deployed as a protype (non-singleton) -->
    <bean  singleton="false">
    </bean>
    <!-- myBean uses singleShotHelper -->
    <bean  >
    <lookup-method
    bean="singleShotHelper"/>
    <property>
    ...
    </property>
    </bean>

    myBean需要一個新的singleShotHelper的實例的時候, 它就會調用它自己的createSingleShotHelper 方法。 值得注意的是:部署beans的人員必須小心地將singleShotHelper作為一個non-singleton部署 (如果確實需要這么做)。如果它作為一個singleton(除非明確說明,否則缺省就是singletion)而部署, 同一個singleShotHelper實例將會每次被返回。

    注意Lookup方法注射能夠同構造函數注射結合(對創建的bean提供可選的構造函數參數), 也可以同setter方法注射結合(在創建的bean之上設置屬性)。

    3.3.3.2. 任意方法的替換

    另一種方法注射沒有lookup方法注入用的多,它用另一個方法實現替換被管理bean的任意一個方法。用戶可以放心跳過這一節(這是個有點高級的特性),除非這個功能確實需要。

    在一個XmlBeanFactory中,對于一個被部署的bean, replaced-method元素可以用來把已存在的方法實現替換為其他的實現。 考慮如下的類,有一個我們想要重寫的computeValue方法:

    ...
    public class MyValueCalculator {
    public String computeValue(String input) {
    ... some real code
    }
    ... some other methods
    }

    需要為新方法定義提供實現 org.springframework.beans.factory.support.MethodReplacer接口的類。

    /** meant to be used to override the existing computeValue
    implementation in MyValueCalculator */
    public class ReplacementComputeValue implements MethodReplacer {
    public Object reimplement(Object o, Method m, Object[] args) throws Throwable {
    // get the input value, work with it, and return a computed result
    String input = (String) args[0];
    ...
    return ...;bean >
    <!-- arbitrary method replacement -->
    <replaced-method  replacer="replacementComputeValue">
    <arg-type>String</arg-type>
    </replaced-method>
    </bean>
    <bean  >
    </bean>

    replaced-method元素中的一個或多個arg-type 元素用來表示,這個被重載方法的方法簽名。注意,參數的簽名只有在方法被重載并且該方法有多個不同的形式的時候才真正需要。為了方便,參數的類型字符串可以使全限定名的子字符串。比如,以下的都匹配 java.lang.String

        java.lang.String
    String
    Str

    因為參數的個數通常就足夠區別不同的可能,所以僅僅使用匹配參數的最短的字符串能夠節省很多鍵入工作。

    3.3.4. 使用bean depends-on="manager"> <property ><ref local="manager"/></property> </bean> <bean />
    
    

    posted on 2008-07-17 10:33 蘆葦 閱讀(311) 評論(0)  編輯  收藏 所屬分類: Spring
    主站蜘蛛池模板: 美女露隐私全部免费直播| 日韩视频在线免费观看| 国产精品无码一二区免费| 污网站免费在线观看| 好看的亚洲黄色经典| 69天堂人成无码麻豆免费视频| 亚洲一区二区三区四区视频 | 免费观看在线禁片| 日本久久久久亚洲中字幕| 97国产在线公开免费观看| 亚洲精品无码一区二区| 亚洲精品无码午夜福利中文字幕| 国产精品亚洲а∨无码播放| 亚洲精品美女在线观看| 国产精品亚洲玖玖玖在线观看| 久久亚洲AV成人无码国产电影 | 女人张腿给男人桶视频免费版| 免费一级全黄少妇性色生活片 | 无码国产精品一区二区免费I6| 一级做受视频免费是看美女| 精品亚洲国产成AV人片传媒| 亚洲男人电影天堂| 99亚洲精品卡2卡三卡4卡2卡| 亚洲成在人天堂一区二区| 亚洲国产成人久久一区久久 | 在线观看亚洲AV日韩AV| 水蜜桃亚洲一二三四在线| 国产成人精品亚洲日本在线| 亚洲欧洲日本天天堂在线观看| 亚洲国产高清视频| 婷婷精品国产亚洲AV麻豆不片| 精品女同一区二区三区免费播放 | 久久亚洲中文字幕无码| 最新亚洲成av人免费看| 日韩成人毛片高清视频免费看| 亚洲成人免费在线| 韩国免费一级成人毛片| 最近中文字幕mv手机免费高清| 午夜dj在线观看免费视频| 精品久久久久成人码免费动漫| 在线观看午夜亚洲一区|