<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
    數(shù)據(jù)加載中……

    《Pro Spring》學(xué)習(xí)筆記(7)--基礎(chǔ)進(jìn)階(2)

    ?

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

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

    主站蜘蛛池模板: xxxxxx日本处大片免费看| 亚洲福利电影在线观看| 日韩中文字幕精品免费一区| 亚洲αv在线精品糸列| eeuss影院ss奇兵免费com| 久久久久久国产精品免费无码| 亚洲乱码国产乱码精品精| 国内精品免费久久影院| 中文字幕人成无码免费视频| 免费人成视频在线观看视频| 久久久久久亚洲精品| 亚洲免费黄色网址| 99久久这里只精品国产免费| 精品亚洲成A人无码成A在线观看| 国产成人yy免费视频| 国产成人亚洲精品| 国产无遮挡又黄又爽免费视频| 久久精品亚洲一区二区| 无码精品国产一区二区三区免费| 精品无码一区二区三区亚洲桃色 | 亚洲精品私拍国产福利在线| 亚洲卡一卡二卡乱码新区| 亚洲午夜国产精品无码| 最近中文字幕免费大全| 亚洲国产精品久久久久久| 在线观看H网址免费入口| 亚洲国产日韩精品| 亚洲成a人片在线观看日本麻豆| 一级毛片aaaaaa视频免费看| 亚洲av无码精品网站| 国产h视频在线观看免费| 免费国产黄网站在线看| 亚洲不卡中文字幕无码| 国产啪精品视频网免费| 国产亚洲精品美女久久久久| 亚洲人成人一区二区三区| 国产精品久久永久免费| 美女视频黄频a免费大全视频| 亚洲Av无码精品色午夜| 韩国欧洲一级毛片免费| 国产免费爽爽视频在线观看 |