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

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

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

    MicroFish

    Open & Open hits
    隨筆 - 33, 文章 - 2, 評論 - 4, 引用 - 0
    數據加載中……

    《Pro Spring》學習筆記(7)--基礎進階(2)

    ?

    ????? Spring1.1中引入了一個很有用的IOC新特性--方法注入(Method Injection)。這能讓我們在組裝bean時獲得極大的靈活性。Spring的方法注入可以分為兩種形式:查詢方法注入(Lookup Method Injection)和方法替換(Method Replacement)。查詢方法注入提供了另一種機制來讓bean獲取它依賴的其它bean,方法替換則可以在不修改源代碼的基礎上,修改任意bean的任何方法的實現。為了提供這兩個功能,Spring借助了CGLIB包。
    ??????先來看看查詢方法注入的使用。想象這樣的情形:我們有一個singleton類型的bean A,它需要使用另一個非singleton類型的bean B來執行一些操作。由于兩個bean的生命周期是不同的,因此我們不能簡單的在bean A的配置中使用ref標簽來要求Spring注入bean B,因為那樣會讓我們每次取得bean A時都使用同一個bean B的實例。回想前面介紹過的BeanFactoryAware接口,我們可以讓bean A實現該接口,這樣就可以在bean A內部使用beanFactory的genBean方法來獲取bean B了。只要我們將bean B配置為非singleton類型,每次使用getBean方法就會得到一個新的bean B的實例。
    ??????使用查詢方法注入,我可以不必實現任何的Spring的接口,也不需要在bean A中顯示的使用getBean方法來獲得bean B。我們只需要在bean A中申明一個查詢方法,然后在bean A的配置文件中指明該查詢方法,那么Spring就會自動的將bean B注入到bean A中去了。由于查詢方法注入的概念相對比較復雜,因此我們還是通過具體的例子來直觀的感受它是如何工作的。
    ??????在這個例子中,我們創建一個非singleton的bean和兩個實現了同一個接口的singleton的bean,一個通過傳統的設值方法注入獲得非singleton的bean,另一個則通過查詢方法注入。
    //The MyHelper Bean
    public class MyHelper {
    ??? public void doSomethingHelpful() {
    ??????? // do something!
    ??? }
    }
    //The DemoBean Interface
    public interface DemoBean {
    ??? public MyHelper getMyHelper();
    ??? public void someOperation();
    }
    //The StandardLookupDemoBean
    public class StandardLookupDemoBean implements DemoBean {
    ??? private MyHelper helper;
    ??? public void setMyHelper(MyHelper helper) {
    ??????? this.helper = helper;
    ??? }
    ??? public MyHelper getMyHelper() {
    ??????? return this.helper;
    ??? }
    ??? public void someOperation() {
    ??????? helper.doSomethingHelpful();
    ??? }
    }
    //The AbstractLookupDemoBean
    public abstract class AbstractLookupDemoBean implements DemoBean {
    ??? public abstract MyHelper getMyHelper();
    ??? public void someOperation() {
    ??????? getMyHelper().doSomethingHelpful();
    ??? }
    }
    <beans>
    ??? <bean id="helper" class="com.apress.prospring.ch5.mi.MyHelper" singleton="false"/>
    ??? <bean id="abstractLookupBean"?
    class="com.apress.prospring.ch5.mi.AbstractLookupDemoBean">
    ??????? <lookup-method name="getMyHelper" bean="helper"/>
    ??? </bean>
    ??? <bean id="standardLookupBean"
    ??? class="com.apress.prospring.ch5.mi.StandardLookupDemoBean">
    ??????? <property name="myHelper">
    ??????????? <ref local="helper"/>
    ??????? </property>
    ??? </bean>
    </beans>
    ????? 可以看到,我們使用了lookup-method來對查詢方法注入進行配置,name屬性告訴Spring需要覆寫bean中的哪個方法,該方法必須是沒有參數的,并且返回類型是我們需要獲得的bean的類型,bean屬性告訴Spring查詢方法需要返回哪個bean。
    ????? 通過DemoBean standardBean = (DemoBean)factory.getBean("standardLookupBean");獲得standardBean,然后比較standardBean.getMyHelper() == standardBean.getMyHelper(),可以發現,直接使用設置方法注入,每次獲得的非singleton的bean實際上是同一個實例。而使用查詢方法注入,則會每次得到一個新的實例,這實際上是因為我們使用factory.getBean("abstractLookupBean")獲得abstractBean時,Spring根據lookup-method的配置,覆寫了查詢方法,從而返回一個新的bean實例,正如前面提到的,這是通過CGLIB包來實現的。
    ????? 值得注意的是,我們將查詢方法定義為抽象的,這不是必須的,但這么做能防止我們忘記了配置lookup-method,從而使用了空的(當然不是我們期望的)查詢方法。
    ????? 好了,讓我們再來看看方法替換,雖然它被劃分為方法注入的一種,但它和我們以前接觸到的注入方式有著很大的差異,以前我們都是注入一個bean,而方法替換則是替換bean中的方法實現。同查詢方法注入一樣,我們還是通過一個例子來理解方法替換的使用。
    //The ReplacementTarget Class
    public class ReplacementTarget {
    ??? public String formatMessage(String msg) {
    ??????? return "<h1>" + msg + "</h1>";
    ??? }
    ??? public String formatMessage(Object msg) {
    ??????? return "<h1>" + msg + "</h1>";
    ??? }
    }
    ???? 現在由于某些原因,我們需要修改以String為參數的方法的實現方式,并且不能修改ReplacementTarget類的源代碼,借助于Spring的方法替換,我們可以輕松地實現。
    ???? 首先,創建一個實現了MethodReplacer接口的類。
    public class FormatMessageReplacer implements MethodReplacer {
    ??? public Object reimplement(Object target, Method method, Object[] args)
    throws Throwable {
    ??????? ...
    ??????? String msg = (String) args[0];
    ??????? return "<h2>" + msg + "</h2>";
    ??????? ...
    ??? }
    }
    <beans>
    ??? <bean id="methodReplacer"
    ????class="com.apress.prospring.ch5.mi.FormatMessageReplacer"/>
    ????<bean id="replacementTarget"
    ??? class="com.apress.prospring.ch5.mi.ReplacementTarget">
    ??????? <replaced-method name="formatMessage" replacer="methodReplacer">
    ??????????? <arg-type>String</arg-type>
    ??????? </replaced-method>
    ??? </bean>
    ??? <bean id="standardTarget"
    ??? class="com.apress.prospring.ch5.mi.ReplacementTarget"/>
    </beans>
    ????? 通過replaced-method標簽來配置需要替換的方法,name屬性指明了需要替換的方法名,replacer屬性指明了用哪個bean來實現替換操作。arg-type是用來指明需要替換的方法的參數類型的,在bean中有重載方法時(像ReplacementTarget類一樣),指明參數類型可以讓Spring明確知道需要替換的是哪個方法。值得注意的是,arg-type是模式匹配的,因此,String將匹配String和StringBuffer。
    ????? 方法替換在很多場合都是有用的,比如我們只想為一個特殊的bean改變它所依賴的另一個bean的實現方法,而不影響其它bean的引用。最好是為每個需要替換的方法,或者是一組重載的方法定義一個替換類,而不要為眾多毫不相關的方法使用同一個替換類。這可以減少很多沒必要的比較,從而提高代碼的執行效率。

    posted on 2006-12-21 10:23 劉璐 閱讀(433) 評論(0)  編輯  收藏 所屬分類: spring

    主站蜘蛛池模板: 国产亚洲视频在线播放| 亚洲精品天堂在线观看| 亚洲精品美女久久久久9999| 亚洲一区精品视频在线| 3d动漫精品啪啪一区二区免费| 亚洲av无码无在线观看红杏| 99精品免费视频| 亚洲国产精品人久久| 在线美女免费观看网站h| 亚洲色大成网站www永久| 国产成人免费网站| 久久精品国产精品亚洲精品 | 亚洲第一精品电影网| 97视频免费观看2区| 亚洲麻豆精品国偷自产在线91| 91在线亚洲精品专区| 国产精品入口麻豆免费观看| 日韩亚洲国产综合久久久| 亚洲精品国产电影午夜| 久九九精品免费视频| 亚洲国产欧美日韩精品一区二区三区| 久久成人a毛片免费观看网站| 亚洲免费在线视频| 免费一本色道久久一区| 久久亚洲中文字幕精品有坂深雪 | 国产精品亚洲精品青青青| 免费人成网站在线观看不卡| 亚洲成a人片在线观看久| 亚洲人精品亚洲人成在线| 全免费a级毛片免费看不卡| 亚洲av乱码一区二区三区香蕉 | 无码成A毛片免费| 国产亚洲国产bv网站在线| 波多野结衣中文一区二区免费| 中文字幕在线免费看线人| 亚洲国产精品综合久久久| 91精品视频在线免费观看| 亚洲熟妇无码一区二区三区 | 麻豆亚洲AV永久无码精品久久| 猫咪社区免费资源在线观看 | 亚洲日本在线电影|