<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

    主站蜘蛛池模板: 亚洲av无码乱码在线观看野外 | 亚洲a∨无码精品色午夜| 亚洲视频免费观看| 亚洲的天堂av无码| 亚洲黄色免费网站| 亚洲av无码片在线观看| 最近2019中文字幕免费看最新| 亚洲乱码一二三四五六区| 114一级毛片免费| 激情内射亚洲一区二区三区爱妻| 18禁免费无码无遮挡不卡网站 | 日韩精品亚洲人成在线观看| 99久久99久久精品免费观看 | a高清免费毛片久久| 亚洲乱码国产一区网址| 久久一区二区免费播放| 亚洲AV无一区二区三区久久| 91手机看片国产永久免费| 国产精品亚洲专区在线观看 | 国产免费一区二区三区在线观看| 亚洲av无码一区二区三区乱子伦 | 久久免费视频99| 亚洲一级片在线观看| 性xxxx视频播放免费| 国产VA免费精品高清在线| 337p欧洲亚洲大胆艺术| 18禁超污无遮挡无码免费网站国产| 在线观看免费亚洲| 亚洲日本乱码在线观看| 免费观看AV片在线播放| 美女被免费网站视频在线| 国产亚洲精品国产| 久九九精品免费视频| 色多多A级毛片免费看| 亚洲视频在线观看网站| 韩国日本好看电影免费看| 一级毛片试看60分钟免费播放| 亚洲视频在线观看| 国产一精品一aⅴ一免费| 无码人妻一区二区三区免费看| 亚洲无人区码一二三码区别图片|