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

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

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

    莊周夢蝶

    生活、程序、未來
       :: 首頁 ::  ::  :: 聚合  :: 管理

    Spring源碼分析:實現AOP(轉載)

    Posted on 2007-04-24 09:37 dennis 閱讀(7540) 評論(0)  編輯  收藏 所屬分類: java 、源碼解讀
        這兩天一直在讀spring1.2的AOP實現源碼,AOP實現原理說起來很簡單,對于實現業務接口的對象使用java代理機制實現,而對于一般的類使用cglib庫實現,但spring的實現還是比較復雜的,不過抓住了本質去看代碼就容易多了。發現一篇04年寫的《spring源碼分析:實現AOP》,倒是不用自己再寫了,04年的時候已經有很多人研讀過spring的源碼,而那時的我還在學校,對java半懂不懂的狀態,就算到現在也不敢說真的懂了,繼續學習、努力。文章如下:

       
    我的問題
           為了完成公司應用開發平臺的設計,這幾天一直在研究Spring的擴展機制。Spring的核心無疑是BeanFactory, ApplicationContext和AOP。在“Spring AOP編程”教程的例子中,是由ProxyFactoryBean來實現的。問題來了,普通的bean和FactoryBean的配置完全是一樣的。那 么,BeanFactory是如何區分普通的Bean和用作Proxy的FactoryBean的?ProxyFactoryBean又是怎樣實現AOP 功能的?(本文還很不完善,我會繼續修改。)
     
    FactoryBean的職責
            FactoryBean在Spring中被當成一種特殊的bean,通過實現FactoryBean接口進行擴展。FactoryBean的職責是:
            l.封裝了創建對象或查找對象的邏輯。
           2.提供了一個中間層,用于支持AOP。

           我們來看一個LocalStatelessSessionProxyFactoryBean的例子。首先,定義Stateless EJB的代理,id為ejbServiceProxy:
           <bean id="ejbServiceProxy" class="LocalStatelessSessionProxyFactoryBean">
               <property name="jndiName">     
                  <value>myEjb</value>
               </property>
               <property name="businessInterface">
                  <value>com.mycompany.MyBusinessInterface</value>
               </property>
          </bean>
     
          然后,再將這個業務邏輯服務對象注入客戶程序:
         <bean id="myAction" class = "samples.myAction">
             <property name="myService">
                 <ref bean="ejbServiceProxy"/>
             </property>
         </bean>

         這樣,客戶程序并不知道myService的實現細節,Spring使用FactoryBean完成了兩者之間的解耦。
     
    準備代碼分析環境
         1. 安裝Eclipse和Spring IDE。
         2. 下載Spring framework源代碼,并導入Eclipse。
         3. 在類路徑創建log4j.properties配置文件,設置如下:
                 log4j.rootLogger=DEBUG, stdout
                 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
                 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
                 log4j.appender.stdout.layout.ConversionPattern=%d{SSS} %p %c{2} - %m%n
         4. 編寫TestCase,跟蹤Console窗口的debug信息。

    FactoryBean源代碼分析
           如果bean實現了FactoryBean接口,BeanFactory將把它作為一個bean工廠,而不是直接作為普通的bean。正常情況下, BeanFactory的getBean("bean")返回FactoryBean生產的bean實例,如果要返回FactoryBean本身的實例, 使用getBean("&bean")的調用方式。
           在分析ProxyFactoryBean之前,我們先分析BeanFactory,它是Spring Framework的基礎。我們看看它是如何分別處理普通的Bean和FactoryBean的。
     
      BeanFactory分析
     
         BeanFactory類圖
     
           如以上的類圖所示,XmlBeanFactory繼承了AbstactBeanFactory抽象類。AbstactBeanFactory類中使用了 Template Method設計模式,其中的模板方法為getBeanDefinition()和createBean()兩個抽象方法。其中 AbstractAutowireCapableBeanFactory類實現了getBeanDefinition()方法, DefaultAutowireCapableBeanFactory類實現了getBeanDefinition()方法。當調用getBean()方 法時,AbstractBeanFactory類定義的邏輯分別調用了這兩個模板方法。

         BeanFactory類的調用順序
           我們暫時不使用ApplicationContext,以簡化分析過程。我在這里使用了“Spring AOP編程”的例子,請參照該教程閱讀。首先,編寫測試用例,代碼如下:

                public class AopTest extends TestCase {
                      XmlBeanFactory factory = null;
                      protected void setUp() throws Exception {
                           super.setUp();
                           InputStream is = new FileInputStream("testaop.xml");
                           factory = new XmlBeanFactory(is);
                      }
                      public void testGetBean() {
                           Bean bean = (Bean)factory.getBean("bean");
                           assertNotNull(bean);
                           bean.theMethod();
                      }
                }
     
           1. 首先,XmlBeanFactory使用XmlBeanDefinitionReader讀入testaop.xml配置文件,后者用 XmlBeanDefinitionParser和DefaultXmlBeanDefinitionParser進行分析,從中得到 BeanDefinition的信息,并保存在XmlBeanDefinitionReader的BeanDefinitionRegistry變量里。
           2. 客戶程序調用getBean方法時,AbstractBeanFactory首先使用transFormedBeanName方法分析傳入的Bean名稱,判斷客戶程序需要FactoryBean本身,還是它所創建的Bean對象。
           3. 接下來,如果bean被定義為singleton模式,AbstractBeanFactory調用createBean方法根據 BeanDefinition信息實例化bean類,然后將該bean實例傳給getObjectForSharedInstance方法并返回 getObjectForSharedInstance的返回對象。GetObjectForSharedInstance方法摘要如類圖所示,首先判斷 bean是否繼承了FactoryBean。如果是,返回FactoryBean的getObject方法(下節我將詳細分析使用 ProxyFactoryBean如何實現AOP);如果不是,返回bean對象。
           4. 如果bean被定義為prototype模式,每次客戶程序請求都會生成新的bean實例,因此,createBean方法直接實例化bean對象并返回。
     
      ProxyFactoryBean如何實現AOP

         ProxyFactoryBean類圖
           FactoryBean接口如下圖所示,共有三個方法getObject,getObjectType,和isSingleton。ProxyFactoryBean實現了FactoryBean接口,它的相關類圖如下:
     

     
         實現AOP的過程
           如上圖所示,ProxyFactoryBean類繼承了AdvisedSupport類,后者繼承了ProxyConfig類并定義了操作advisor 和interceptor的接口,以支持AOP。當BeanFactory實例化ProxyFactoryBean時,根據配置文件的定義將關于 advice,pointcut,advisor,所代理的接口和接口實現類的所有信息傳給ProxyFactoryBean。
           當客戶程序調用BeanFactory的getBean方法時,ProxyFactory使用JdkDynamicAopProxy實例化 BeanImpl類,并用JdkDynamicAopProxy的invoke方法執行advice。至于執行advice的時機,由 ProxyFactoryBean調用RegexpMethodPointcutAdvisor進行判斷。


    主站蜘蛛池模板: 成年女人免费v片| 久久久久久精品成人免费图片| 特级毛片A级毛片100免费播放| 四虎影视永久在线精品免费| 久久99毛片免费观看不卡| 91成人免费观看| 国产男女性潮高清免费网站| 亚洲人成中文字幕在线观看| 亚洲国产精品成人综合久久久| 久久亚洲AV成人无码国产最大| 高清一区二区三区免费视频 | 久久久久久免费一区二区三区| 亚洲精品无码成人片久久| 国产精品亚洲午夜一区二区三区 | 亚洲人成色99999在线观看| 香蕉免费一级视频在线观看| 成熟女人特级毛片www免费| 亚洲av日韩综合一区二区三区| avtt亚洲天堂| 亚洲影视自拍揄拍愉拍| 精品久久久久国产免费| 亚洲国产综合91精品麻豆| 美女一级毛片免费观看| 亚洲中文字幕无码永久在线| 久久人午夜亚洲精品无码区 | 亚洲影视一区二区| 女人被免费视频网站| 亚洲国产精品成人精品小说| 免费做爰猛烈吃奶摸视频在线观看| 亚洲成av人在线观看网站| 国产人成免费视频网站| 亚洲av无码国产精品夜色午夜 | 亚洲av无码成人精品区一本二本 | xxxxxx日本处大片免费看| 日韩a级毛片免费视频| 在线观看亚洲AV每日更新无码 | 亚洲伊人成无码综合网 | 毛片免费观看的视频| h在线看免费视频网站男男| 亚洲国产一区视频| 成年免费大片黄在线观看com|