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

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

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

    kapok

    垃圾桶,嘿嘿,我藏的這么深你們還能找到啊,真牛!

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      455 隨筆 :: 0 文章 :: 76 評論 :: 0 Trackbacks

    http://blog.blogchina.com/category.307634.html

    1,控制反轉(IoC = Inversion of Control) & 依賴注入(DI = Dependency Injection)
       IoC:由容器控制程序之間的關系,而非傳統現實中,由程序代碼直接控制。控制權由應用代碼中轉到了外部容器,控制權的轉移,即所謂反轉。
       DI:即組件之間的依賴關系由容器在運行期決定,由容器動態的將某種依賴關系注入到組件之中。

    2, 依賴注入的幾種實現類型
       1)接口注入:
       我們常常借助接口來將調用與實現者分離:
       public class ClassA {
         private InterfaceB clzB;
         public doSomething() {
           Ojbect obj = Class.forName(Config.BImplementation).newInstance();
           clzB = (InterfaceB)obj;
           clzB.doIt()
         }
          ......
       }
       在上面的代碼中,ClassA依賴于InterfaceB的實現,如何獲得InterfaceB實現類的實例?傳統的方法是在代碼中創建InterfaceB實現類的實例,并將其賦予ClzB。
       而這樣一來,ClassA在編譯期即依賴于InterfaceB的實現。為了將調用者與實現者在編譯期分離,于是有了上面的代碼,我們根據預先在配置文件中設定的實現類的類名(Config.BImplementation),動態加載實現類,并通過InterfaceB強制轉型后為ClassA所用。這就是接口注入的一個最原始的雛形。
       而對于一個接口注入型IoC容器而言,加載接口實現并創建其實例的工作由容器完成。如:
       public class ClassA {
         private InterfaceB clzB;
         public Object doSomething(InterfaceB b) {
           clzB = b;
           return clzB.doIt();
         }
          ......
       }
       在運行期,InterfaceB實例將由容器提供。

       2)設值注入
       即通過類的setter方法完成依賴關系的設置。

       3)構造子注入
       構造子注入,即通過構造函數完成依賴關系的設定,如:
       public class DIByConstructor {
         private final DataSource dataSource;
         private final String message;
         public DIByConstructor(DataSource ds, String msg) {
           this.dataSource = ds;
           this.message = msg;
         }
          ......
       }
       在構造子注入的依賴注入機制中,依賴關系是通過類構造函數建立,容器通過調用類的構造方法,將其所需的依賴關系注入其中。

       4)幾種依賴注入模式的對比總結
       接口注入模式:由于其歷史悠久,在很多容器中都已經得到了應用。但由于其在靈活性,易用性上不如其它兩種注入模式,因為在IOC的專題世界內并不被看好。
       設值注入的優勢:第一,對于習慣了傳統JavaBean開發的程序員而言,通過setter方法設定依賴關系顯得更加直觀,更加自然;第二,如果依賴關系(或繼承關系)較為復雜,那么構造子注入模式的構造函數也會相當龐大(我們需要在構造函數中設定所有的依賴關系),此時設值注入模式往往更為簡潔;第三,對于某些第三方類庫而演,可能要求我們的組件必須提供一個默認的構造函數,此時構造子注入模式的依賴注入機制就體現出其局限性,難以完成我們期望的功能。
       構造子注入的優勢:第一,"在構造期即創建一個完整合法的對象",對于這條java設計原則,構造子注入無疑是最好的響應者;第二,避免了繁瑣的setter方法的編寫,所有依賴關系均在構造函數中設定,依賴關系集中呈現,更加易讀;第三,由于沒有setter方法,所有依賴關系均在構造時由容器一次性設定,因此組件在被創建之后即處于相對"不變"的穩定狀態,無需擔心上層代碼在調用過程中就執行setter方法對組件依賴關系產生破壞,特別是對于Singleton模式的組件而言,這可能對整個系統產生重大的影響;第四,同樣,對于關聯關系僅在構造函數中表達,只有組件創建者需要關心組件內部的依賴關系。對于調用者而言,組件中的依賴關系處于黑盒之中。對上層屏蔽不必要的信息,也為系統的層次清晰性提供了保證;第五,通過構造子注入,意味著我們可以在構造函數中決定依賴關系的注入順序,對于一個大量依賴外部服務的組件而言,依賴關系的獲得順序可能非常重要,比喻某個依賴關系注入的先決條件是組件的DataSource及相關資源已經被設定。

    3,Spring Bean封裝機制
       Spring從核心而言,是一個DI容器,其設計哲學是提供一個無侵入式的高擴展性框架。即無需代碼中涉及Spring專有類,即可將其納入Spring容器進行管理。
       作為對比,EJB則是一個高度侵入性的框架規范,它制定了眾多的接口和編碼規范,要求實現者必須遵從。侵入性的后果就是,一旦系統基于侵入性框架設計開發,那么之后任何脫離這個框架的企圖都將付出極大的代價。
       為了避免這種情況,實現無侵入性的目標。Spring大量引入了java的Reflection機制,通過動態調用的方式避免硬編碼方式的約束,并在此基礎上建立了其核心組件BeanFactory,以此作為其依賴注入機制的實現基礎。
       org.springframework.beans包中包括了這些核心組件的實現類,核心中的核心為BeanWrapper和BeanFactory類。這兩個類從技術角度而言并不復雜,但對于Spring框架而言,卻是關鍵所在。

    4,Bean Wrapper
       所謂依賴注入,即在運行期由容器將依賴關系注入到組件之中。講得通俗點,就是在運行期,由Spring根據配置文件,將其他對象的引用通過組件提供的setter方法進行設定。
       我們知道,如果動態設置一個對象屬性,可以借助Java的Reflection機制完成:
       Class cls = Class.forName("net.xiaxin.beans.User");
       Method mtd = cls.getMethod("setName",new Class[]{String.class});
       Object obj = (Object)cls.newInstance();
       mtd.invoke(obj,new Object[]{"Erica"});
       return obj;
       上面我們通過動態加載了User類,并通過Reflection調用了User.setName方法設置其name屬性。對于這里的例子而言,處于簡潔,我們將類名和方法名都以常量的方法硬編碼。假設這些常量都是通過配置文件讀入,那我們就實現了一個最簡單的BeanWrapper。這個BeanWrapper的功能很簡單,提供一個設置JavaBean屬性的通用方法(Apache BeanUtils類庫中提供了大量針對Bean的輔助工具,如果有興趣可以下載一份源代碼加以研讀)。
       Spring BeanWrapper基于同樣的原理,提供了一個更加完善的實現??纯慈绾瓮ㄟ^Spring BeanWrapper操作一個JavaBean:
       Object obj = Class.forName("net.xiaxin.beans.User").newInstance();
       BeanWrapper bw = new BeanWrapperImpl(obj);
       bw.setPropertyValue("name", "Erica");
       System.out.println("User name=>"+bw.getPropertyValue("name"));
       對比之前的代碼,相信大家已經知道BeanWrapper的實現原理。
       誠然,通過這樣的方式設定JavaBean屬性實在繁瑣,但它卻提供了一個通用的屬性設定機制,而這樣的機制,也正是Spring依賴注入機制所依賴的基礎。
       通過BeanWrapper,我們可以無需在編碼時就指定JavaBean的實現類和屬性值,通過在配置文件加以設定,就可以在運行期動態創建對象并設定其屬性(依賴關系)。
       上面的代碼中,我們僅僅指定了需要設定的屬性名"name",運行時,BeanWrapper將根據JavaBean規范,動態調用對象的"setName"方法進行屬性設定。屬性名可以包含層次,如對于屬性名"address.zipcode",BeanWrapper會調用"getAddress().setZipcode"方法。

    5,Bean Factory
       顧名思義,負責創建并維護Bean實例。
       Bean Factory負責根據配置文件創建Bean實例,可以配置的項目有:
       1)Bean屬性值以及依賴關系(對其他Bean的引用)
       2)Bean創建模式(是否Singleton模式,即是否只針對指定類維持全局唯一的實例)
       3)Bean初始化和銷毀方法
       4)Bean的依賴關系
       下面是一個較為完整的Bean配置示例:

      Spring Bean Configuration Sample

      id="TheAction" ⑴
      class="net.xiaxin.spring.qs.UpperAction" ⑵
      singleton="true" ⑶
      init-method="init" ⑷
      destroy-method="cleanup" ⑸
      depends-on="ActionManager" ⑹
    >
     
        HeLLo ⑺
     
     
       
     
     
        ⑻
     


     
        java:comp/env/jdbc/sample
     


      (1)id:Java Bean在BeanFactory中的唯一標識,代碼中通過BeanFactory獲取JavaBean實例時需以此作為索引名稱。
      (2)class:Java Bean類名。
      (3)singleton:指定此Java Bean是否采用單例(singleton)模式,如果設置為"true",則在BeanFactory作用范圍內,只維護此Java Bean的一個實例,代碼通過BeanFactory獲得此Java Bean實例的引用。反之,如果設為"false",則通過BeanFactory獲取此Java Bean實例時,BeanFactory每次都將創建一個新的實例返回。
      (4)init-method:初始化方法,此方法將在BeanFactory創建JavaBean實例之后,在向應用層返回引用之前執行。一般用語一些資源的初始化工作。
      (5)destroy-method:銷毀方法。此方法將在BeanFactory銷毀的時候執行,一般用于資源釋放。
      (6)depends-on:Bean依賴關系。一般情況下無需設定。Spring會根據情況組織各個依賴關系的構建工作(這里示例中的depends-on屬性非必須)。只有在某些特殊情況下,如JavaBean中的某些靜態變量需要進行初始化(這是一種BadSmell,應該在設計上避免)。通過depends-on指定其依賴關系可以保證在此Bean加載之前,首先對depends-on所指定的資源進行加載。
      (7):通過節點可指定屬性值。BeanFactory將自動根據JavaBean對應的屬性類型加以匹配。上面的"desc"屬性提供了一個null值的設定示例,需要注意的是代表一個空字符串,如果需要將屬性值設定為null,必須使用節點。
      (8):指定了屬性對BeanFactory中其他Bean的引用關系。示例中,TheAction的dataSource屬性引用了id為dataSource的Bean。BeanFactory將在運行期創建dataSource bean實例,并將其引用傳入TheAction Bean的dataSource屬性中。
       下面的代碼演示了如何通過BeanFactory獲取Bean實例:
       InputStream is = new FileInputStream("bean.xml");
       XmlBeanFactory factory = new XmlBeanFactory(is);
       Action action = (Action) factory.getBean("TheAction");
       此時我們獲得的Action實例,由BeanFactory進行加載,并根據配置文件進行了初始化和屬性設定。

       聯合上面關于BeanWrapper的內容,我們可以看到,BeanWrapper實現了針對單個Bean的屬性設定操作。而BeanFactory則是針對多個Bean的管理容器,根據給定的配置文件,BeanFactory從中讀取類名,屬性名/值,然后通過Reflection機制進行Bean加載和屬性指定。

    6,ApplicationContext
       BeanFactory提供了針對JavaBean的管理功能,而ApplicationContext提供了一個更為框架化的實現(從上面的示例中可以看出,BeanFactory的使用方式更加類似一個API,而非Framework style)。
       ApplicationContext覆蓋了BeanFactory的所有功能,提供了更為開放式的實現(如對于Web應用,我們可以在web.xml中對ApplicationContext進行配置)。
       相對于BeanFactory而言,ApplicationContext提供了以下擴展功能:
       1)國際化支持:
          我們可以在Beans.xml文件中,對程序中的語言信息(如提示信息)進行定義,將程序中的提示信息抽取到配置文件中加以定義,為我們進行應用的各語言版本轉換提供了極大的靈活性。
       2)資源訪問
          支持對文件和URL的訪問
       3)事件傳播
          事件傳播特性為系統中狀態改變時的檢測提供了良好的支持。
       4)多實例加載
          可以在同一個應用中加載多個Context實例。

       下面分別對這些特性進行介紹:
       1)國際化支持
       國際化支持在實際開發中可能是最常用的特性。對于一個需要支持不同語言環境的應用而言。我們所采取的最常用的策略一般是通過一個獨立的資源文件(如一個properties文件)完成所有語言信息(如界面上的提示信息)的配置。Spring對這種傳統的方式進行了封裝,并提供了更加強大的功能,如信息的自動裝配以及熱部署功能(配置文件修改后自動讀取,而無需重新啟動程序),下面是一個典型的示例:

      Spring Quick Start
          class="org.springframework.context.support.ResourceBundleMessageSource">
       
         
            messages
         
       
     

       這里聲明了一個名為messageSource的Bean(注意對于Message定義,Bean ID必須為messageSource,這是目前Spring的編碼規約),對應類為ResourceBundleMessageSource,目前Spring中提供了兩個MessageSource接口的實現,即ResourceBundleMessageSource和ReloadableResourceBundleMessageSource,后者提供了無需重啟即可重新加載配置信息的特性。
       在配置節點中,我們指定了一個配置名"messages"。Spring會自動在CLASSPATH根路徑中按照如下順序搜尋配置文件并進行加載(以Locale為zh_CH為例):
    messages_zh_CN.properties
    messages_zh.properties
    messages.properties
    messages_zh_CN.class
    messages_zh.class
    messages.class
    (Spring實際上調用了JDK的ResourceBundle讀取配置文件)
       示例中包含了兩個配置文件,內容如下:
    messages_zh_CN.properties:
       userinfo=當前登陸用戶:[{0}] 登陸時間:[{1}]
    messages_en_US.properties:
       userinfo=Current Login user:[{0}] Login time:[{1}]
       我們可以通過下面的語句進行測試:
       ApplicationContext ctx=new
       FileSystemXmlApplicationContext("bean.xml");
       Object[] arg = new Object[]{"Erica", Calendar.getInstance().getTime()};
       //以系統默認Locale加載信息(對于中文WinXP而言,默認為zh_CN)
       String msg = ctx.getMessage("userinfo", arg);
       System.out.println("Message is ===> "+msg);
       代碼中,我們將一個Object數組arg作為參數傳遞給ApplicationContext.getMessage方法,這個參數中包含了出現在最終文字信息中的可變內容,ApplicationContext將根據參數中的Locale信息對其進行處理(如針對不同Locale設定日期輸出格式),并用其替換配置文件中的{n}標識(n代表參數數組中的索引,從1開始)。
       根據當前默認Locale"zh_CH",getMessage方法自動加載了message_zh_CH.properties文件。JVM會根據當前系統的Locale設定進行相應處理??梢酝ㄟ^在JVM啟動參數中追加"-Duser.language=en"來設定當前JVM語言類型,通過JVM級的設定,結合國際化支持功能,我們可以較為簡單的實現多國語言系統的自動部署切換。
       getMessage還有一個中指定Locale參數的版本,直接指定加載對應的properties文件:
      String msg = ctx.getMessage("userinfo", arg, Locale.US);

      2)資源訪問
      ApplicationContext.getResource方法提供了對資源文件訪問支持,如:
      Resource rs = ctx.getResource("classpath:config.properties");
      File file = rs.getFile();
      上例從CLASSPATH根路徑中查找config.properties文件并獲取其文件句柄。getResource方法的參數為一個資源訪問地址,如:
        file:C:/config.properties
        /config.properties
        classpath:config.properties
        注意getResource返回的Resource并不一定實際存在,可以通過Resource.exists()方法對其進行判斷。

         3)事件傳播
        ApplicationContext基于Observer模式(java.util包中有對應實現),提供了針對Bean的事件傳播功能。通過Application.publishEvent方法,我們可以將事件通知系統內所有的ApplicationListener。
        事件傳播的一個典型應用是,當Bean中的操作發生異常(如數據庫連接失敗),則通過事件傳播機制通知異常監聽器進行處理。
        在目前版本的Spring中,事件傳播部分的設計還有待改進。同時,如果能夠進一步支持異步事件處理機制,無疑更具吸引力。
        org.springframework.context.event.ApplicationEventMulticasterImpl實現了事件傳播機制,目前還相當簡陋。
       在運行期,ApplicationContext會自動在當前的所有Bean中尋找ApplicationListener接口的實現,并將其作為事件接收對象。當Application.publishEvent方法調用時,所有的ApplicationListener接口實現都會被激發,每個ApplicationListener可根據事件的類型判斷是否是自己需要處理的事件。

    7,Web Context
       對于Web應用,Spring提供了可配置的ApplicationContext加載機制。
       加載器目前有兩種選擇:ContextLoaderListener和ContextLoaderServlet。這兩者在功能上完全等同,只是一個是基于Servlet2.3版本中新引入的Listener接口實現,而另一個基于Servlet接口實現,開發中可根據目標Web容器的實際情況進行選擇。
       配置非常簡單,在web.xml中增加:
     
       
            org.springframework.web.context.ContextLoaderListener
       
     
       或:
     
         context
        
             org.springframework.web.context.ContextLoaderServlet
        
         1
     
       通過以上配置,Web容器會自動加載/WEB-INF/applicationContext.xml初始化ApplicationContext實例,如果需要指定配置文件位置,可通過context-param加以指定:
     
         contextConfigLocation
         /WEB-INF/myApplicationContext.xml
     
      配置完成之后,即可通過:WebApplicationContextUtils.getWebApplicationContext方法在Web應用中獲取ApplicationContext引用。

    8,Aspect Oriented Programming
       OOP(面向對象編程)針對業務處理過程的實體及其屬性和行為進行抽象封裝,以獲得更加清晰高效的邏輯單元劃分。
       AOP(面向切面編程)針對業務處理過程中的切面進行提取,它所面對的是處理過程中的某個步驟和階段,以獲得邏輯過程中各部分之間低耦合性的隔離效果。
       AOP還有另外一個重要特點:源碼組成無關性。倘若應用中通過某個具體的業務邏輯類實現了獨立的權限檢查,而請求調度方法通過預編碼調用這個權限模塊實現權限管理,那么這也不算是AOP。對于AOP組件而言,很重要的一點就是源碼組成無關性,所謂源碼組成無關性,體現在具體設計中就是AOP組件必須與應用代碼無關,簡單來講,就是應用代碼可以脫離AOP組件獨立編譯。
       為了實現源碼組成無關性,AOP往往通過預編譯方式(如AspectJ)和運行期動態代理模式(如Spring AOP和JBoss AOP)實現。
       下面先來看AOP中幾個比較重要的概念:
       1)切面(Aspect)
          通過切面,我們可以將系統中各個不同層次上的問題隔離開來,實現統一集約式處理。各個切面只需要集中于自己領域內的邏輯實現。這一方面使得開發邏輯更加清晰,專業化分工更加易于進行;另一方面,由于切面的隔離,降低了偶合性,我們就可以在不同的應用中將各個切面組合使用,從而使得代碼可重用性大大增強。
       2)連接點(JoinPoint)
          程序運行過程中的某個階段點。如某個方法調用,或者某個異常被拋出。
       3)處理邏輯(Advice)
          在某個連接點所采用的處理邏輯。處理邏輯調用模式通常有三種:
          第一:Around,在連接點前后插入預處理過程和后處理過程;
          第二:Before,僅在連接點之前插入預處理過程;
          第三:Throw,在連接點拋出異常時進行異常處理。
       4)切點(PointCut)
          一系列連接點的集合,它指明處理方式(Advice)將在何時被觸發。

    9,AOP in Spring
       Spring中提供的內置AOP支持,是基于動態AOP機制實現。從技術角度來講,所謂動態AOP,即通過動態Proxy模式,在目標對象的方法調用前后插入相應的處理代碼。Spring AOP中的動態Proxy模式,則是基于Java Dynamic Proxy(面向Interface)和CGLIB(面向Class)實現。

    posted on 2005-03-30 17:03 笨笨 閱讀(996) 評論(0)  編輯  收藏 所屬分類: J2EE 、HibernateAndSpring 、ALL
    主站蜘蛛池模板: 久久狠狠高潮亚洲精品| 亚洲福利中文字幕在线网址| 国产V亚洲V天堂无码久久久| 国产精品亚洲专区无码唯爱网| 野花高清在线观看免费完整版中文 | 亚洲欧洲久久久精品| 免费看一级高潮毛片| 久久亚洲国产精品五月天婷| 免费无码AV一区二区| 亚洲国产天堂久久综合| 久久成人永久免费播放| 久久精品国产亚洲Aⅴ蜜臀色欲| eeuss影院免费直达入口| 亚洲中文字幕无码爆乳AV| 在线观看人成视频免费无遮挡| 久久亚洲免费视频| 免费人成在线观看网站品爱网| 91在线亚洲精品专区| 67194熟妇在线永久免费观看| 亚洲人成未满十八禁网站| 亚洲成A∨人片天堂网无码| 久久久久久久国产免费看| 亚洲av日韩av不卡在线观看| 手机在线看永久av片免费| 九九精品国产亚洲AV日韩| 国产亚洲精品福利在线无卡一| 无码国产精品一区二区免费vr| 精品丝袜国产自在线拍亚洲| 国产无遮挡又黄又爽免费视频 | 十八禁的黄污污免费网站| 国产成人亚洲综合色影视| 波多野结衣免费在线| 精品亚洲成a人在线观看| 亚洲午夜国产片在线观看| 久久国产免费观看精品3| 久久亚洲精品无码网站| 色噜噜AV亚洲色一区二区| 在线观看的免费网站| 国产精品1024在线永久免费 | 亚洲精品成人久久久| 最好看最新的中文字幕免费|