SpringFramework的ProxyFactory和ProxyFactoryBean實現分析

    在此記錄下,以便後面用到,再者,若是須要還能夠繼續更新此文。有些細節步驟被我省略了,建議讀者本身去讀源碼。java

1.ProxyFactory

    getProxy()方法,依據咱們對Proxy屬性的設置,生成JdkDynamicAopProxy或者CglibAopProxy,咱們這裏分析JdkDynamicAopProxy的場景。原圖在Gtihub上。git

  • 步驟7處,是JDK的動態代理,當咱們調用方法時,實際執行的是JdkDynamicAopProxy的invoke方法。
  • 步驟13處,將advice轉爲adviceInterceptor。
  • 步驟19處,有遞歸,不斷的處理咱們定義的Advice(咱們的定義的Advice會被放到一個List中),到最後,才執行真正被代理對象的方法。
  • 調用鏈的設計,有點奧妙,我的以爲,待仔細分析。爲何這麼說,請看下以下三個類的invoke(MethodInvocation)方法。這種方式我在Spring-tx(事物模塊)模塊中看到過。
org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor
org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor
org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor

 

2.ProxyFactoryBean

    ProxyFactoryBean不一樣於ProxyFactory,ProxyFactoryBean是個FactoryBean(若是是熟悉這個interface接口的同窗看到這個應該能想到點什麼了吧,這裏),它有個getObject()方法,Spring IOC在容器中由BeanDefinition生成bean對象時,會調用此方法,將getObject()的返回值做爲bean對象。因此咱們從getObjects()開始分析起。github

     這裏咱們分析JdkDynamicAopProxy時候的場景。原圖在Github上。spring

  • 步驟14,咱們在調用被代理對象的方法時,調用的是JdkDynamicAopProxy的invoke(),以後的操做就和ProxyFactory的同樣了,看上面ProxyFactory的分析。
  • 注意步驟2中的實現,關鍵代碼以下,這裏interceptorNames中的值多數狀況下是Spring bean的ID。

 

for (String name : this.interceptorNames) {
    if (logger.isTraceEnabled()) {
        logger.trace("Configuring advisor or advice '" + name + "'");
    }

    if (name.endsWith(GLOBAL_SUFFIX)) {
        if (!(this.beanFactory instanceof ListableBeanFactory)) {
            throw new AopConfigException(
                    "Can only use global advisors or interceptors with a ListableBeanFactory");
        }
        addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
                name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
    } else {
        Object advice;
        if (this.singleton || this.beanFactory.isSingleton(name)) {
            //name是bean的Id,因此從beanFactory中直接getBean()便可。
            advice = this.beanFactory.getBean(name);
        } else {
            // It's a prototype Advice or Advisor: replace with a prototype.
            // Avoid unnecessary creation of prototype bean just for advisor chain initialization.
            advice = new PrototypePlaceholderAdvisor(name);
        }
        //將獲得的advice加入到攔截器鏈中
        addAdvisorOnChainCreation(advice, name);
    }
}

 

    還有不少關鍵點沒有寫出來,我我的以爲仍是本身去看源碼比較好,有些地方很難用有限的語言清晰的描述出來。this

 

3.Reference

  • SpringFramework-3.2.8.RELEASE。
  • 精通Spring 3.x 企業應用開發實戰(雖然我的不喜歡精通二字,可是本書仍是比較好的,相對其它Spring書籍)。
相關文章
相關標籤/搜索