<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

    主站蜘蛛池模板: 大地资源免费更新在线播放| 真实国产乱子伦精品免费| 亚洲三级视频在线观看| 成全高清在线观看免费| 日韩精品无码区免费专区| 亚洲妓女综合网99| 亚洲精品国产日韩无码AV永久免费网| 国产禁女女网站免费看| 久久精品国产精品亚洲色婷婷 | 亚洲精品国产字幕久久不卡| 亚洲国产福利精品一区二区| 中文字幕在线观看免费视频| 亚洲自偷自拍另类图片二区| 羞羞视频免费网站在线看| 亚洲午夜无码久久久久| 1区2区3区产品乱码免费| 亚洲AV一二三区成人影片| 在线看片人成视频免费无遮挡| 亚洲AV网一区二区三区| 中文免费观看视频网站| 亚洲综合一区国产精品| 久久久久久国产精品免费免费男同| 亚洲综合成人网在线观看| 免费无码A片一区二三区| 亚洲精品人成网线在线播放va| 亚洲精品无码成人片在线观看| 免费观看在线禁片| 久久亚洲国产最新网站| 成人无码区免费A片视频WWW| 中文字幕亚洲综合久久2| 久久99九九国产免费看小说| 亚洲AV成人一区二区三区观看| 亚洲精品成人无限看| 无码国产精品一区二区免费式直播| 亚洲变态另类一区二区三区| 中文字幕精品无码亚洲字| 一本久久免费视频| 中文字幕在亚洲第一在线| 亚洲一级免费毛片| 日本高清不卡中文字幕免费| 亚洲91av视频|