下面再看看 Spring 是如何調(diào)用攔截器的,下面是這個(gè)過(guò)程的時(shí)序圖:
圖 20.Spring 調(diào)用攔截器
以上所說(shuō)的都是 Jdk 動(dòng)態(tài)代理,Spring 還支持一種 CGLIB 類代理,感興趣自己看吧。
Spring 中設(shè)計(jì)模式分析
Spring 中使用的設(shè)計(jì)模式也很多,比如工廠模式、單例模式、模版模式等,在《 Webx 框架的系統(tǒng)架構(gòu)與設(shè)計(jì)模式》、《 Tomcat 的系統(tǒng)架構(gòu)與模式設(shè)計(jì)分析》已經(jīng)有介紹,這里就不贅述了。這里主要介紹代理模式和策略模式。
代理模式
代理模式原理
代理模式就是給某一個(gè)對(duì)象創(chuàng)建一個(gè)代理對(duì)象,而由這個(gè)代理對(duì)象控制對(duì)原對(duì)象的引用,而創(chuàng)建這個(gè)代理對(duì)象就是可以在調(diào)用原對(duì)象是可以增加一些額外的操作。下面是代理模式的結(jié)構(gòu):
圖 21. 代理模式的結(jié)構(gòu)
- Subject:抽象主題,它是代理對(duì)象的真實(shí)對(duì)象要實(shí)現(xiàn)的接口,當(dāng)然這可以是多個(gè)接口組成。
- ProxySubject:代理類除了實(shí)現(xiàn)抽象主題定義的接口外,還必須持有所代理對(duì)象的引用
- RealSubject:被代理的類,是目標(biāo)對(duì)象。
Spring 中如何實(shí)現(xiàn)代理模式
Spring Aop 中 Jdk 動(dòng)態(tài)代理就是利用代理模式技術(shù)實(shí)現(xiàn)的。在 Spring 中除了實(shí)現(xiàn)被代理對(duì)象的接口外,還會(huì)有 org.springframework.aop.SpringProxy 和 org.springframework.aop.framework.Advised 兩個(gè)接口。Spring 中使用代理模式的結(jié)構(gòu)圖如下:
圖 22. Spring 中使用代理模式的結(jié)構(gòu)圖
$Proxy 就是創(chuàng)建的代理對(duì)象,而 Subject 是抽象主題,代理對(duì)象是通過(guò) InvocationHandler 來(lái)持有對(duì)目標(biāo)對(duì)象的引用的。
Spring 中一個(gè)真實(shí)的代理對(duì)象結(jié)構(gòu)如下:
清單 10 代理對(duì)象 $Proxy4
public class $Proxy4 extends java.lang.reflect.Proxy implements
org.springframework.aop.framework.PrototypeTargetTests$TestBean
org.springframework.aop.SpringProxy
org.springframework.aop.framework.Advised
{
java.lang.reflect.Method m16;
java.lang.reflect.Method m9;
java.lang.reflect.Method m25;
java.lang.reflect.Method m5;
java.lang.reflect.Method m2;
java.lang.reflect.Method m23;
java.lang.reflect.Method m18;
java.lang.reflect.Method m26;
java.lang.reflect.Method m6;
java.lang.reflect.Method m28;
java.lang.reflect.Method m14;
java.lang.reflect.Method m12;
java.lang.reflect.Method m27;
java.lang.reflect.Method m11;
java.lang.reflect.Method m22;
java.lang.reflect.Method m3;
java.lang.reflect.Method m8;
java.lang.reflect.Method m4;
java.lang.reflect.Method m19;
java.lang.reflect.Method m7;
java.lang.reflect.Method m15;
java.lang.reflect.Method m20;
java.lang.reflect.Method m10;
java.lang.reflect.Method m1;
java.lang.reflect.Method m17;
java.lang.reflect.Method m21;
java.lang.reflect.Method m0;
java.lang.reflect.Method m13;
java.lang.reflect.Method m24;
int hashCode();
int indexOf(org.springframework.aop.Advisor);
int indexOf(org.aopalliance.aop.Advice);
boolean equals(java.lang.Object);
java.lang.String toString();
void sayhello();
void doSomething();
void doSomething2();
java.lang.Class getProxiedInterfaces();
java.lang.Class getTargetClass();
boolean isProxyTargetClass();
org.springframework.aop.Advisor; getAdvisors();
void addAdvisor(int, org.springframework.aop.Advisor)
throws org.springframework.aop.framework.AopConfigException;
void addAdvisor(org.springframework.aop.Advisor)
throws org.springframework.aop.framework.AopConfigException;
void setTargetSource(org.springframework.aop.TargetSource);
org.springframework.aop.TargetSource getTargetSource();
void setPreFiltered(boolean);
boolean isPreFiltered();
boolean isInterfaceProxied(java.lang.Class);
boolean removeAdvisor(org.springframework.aop.Advisor);
void removeAdvisor(int)throws org.springframework.aop.framework.AopConfigException;
boolean replaceAdvisor(org.springframework.aop.Advisor,
org.springframework.aop.Advisor)
throws org.springframework.aop.framework.AopConfigException;
void addAdvice(org.aopalliance.aop.Advice)
throws org.springframework.aop.framework.AopConfigException;
void addAdvice(int, org.aopalliance.aop.Advice)
throws org.springframework.aop.framework.AopConfigException;
boolean removeAdvice(org.aopalliance.aop.Advice);
java.lang.String toProxyConfigString();
boolean isFrozen();
void setExposeProxy(boolean);
boolean isExposeProxy();
}
|
策略模式
策略模式原理
策略模式顧名思義就是做某事的策略,這在編程上通常是指完成某個(gè)操作可能有多種方法,這些方法各有千秋,可能有不同的適應(yīng)的場(chǎng)合,然而這些操作方法都有可能用到。各一個(gè)操作方法都當(dāng)作一個(gè)實(shí)現(xiàn)策略,使用者可能根據(jù)需要選擇合適的策略。
下面是策略模式的結(jié)構(gòu):
圖 23. 策略模式的結(jié)構(gòu)
- Context:使用不同策略的環(huán)境,它可以根據(jù)自身的條件選擇不同的策略實(shí)現(xiàn)類來(lái)完成所要的操作。它持有一個(gè)策略實(shí)例的引用。創(chuàng)建具體策略對(duì)象的方法也可以由他完成。
- Strategy:抽象策略,定義每個(gè)策略都要實(shí)現(xiàn)的策略方法
- ConcreteStrategy:具體策略實(shí)現(xiàn)類,實(shí)現(xiàn)抽象策略中定義的策略方法
Spring 中策略模式的實(shí)現(xiàn)
Spring 中策略模式使用有多個(gè)地方,如 Bean 定義對(duì)象的創(chuàng)建以及代理對(duì)象的創(chuàng)建等。這里主要看一下代理對(duì)象創(chuàng)建的策略模式的實(shí)現(xiàn)。
前面已經(jīng)了解 Spring 的代理方式有兩個(gè) Jdk 動(dòng)態(tài)代理和 CGLIB 代理。這兩個(gè)代理方式的使用正是使用了策略模式。它的結(jié)構(gòu)圖如下所示:
圖 24. Spring 中策略模式結(jié)構(gòu)圖
在上面結(jié)構(gòu)圖中與標(biāo)準(zhǔn)的策略模式結(jié)構(gòu)稍微有點(diǎn)不同,這里抽象策略是 AopProxy 接口,Cglib2AopProxy 和 JdkDynamicAopProxy 分別代表兩種策略的實(shí)現(xiàn)方式,ProxyFactoryBean 就是代表 Context 角色,它根據(jù)條件選擇使用 Jdk 代理方式還是 CGLIB 方式,而另外三個(gè)類主要是來(lái)負(fù)責(zé)創(chuàng)建具體策略對(duì)象,ProxyFactoryBean 是通過(guò)依賴的方法來(lái)關(guān)聯(lián)具體策略對(duì)象的,它是通過(guò)調(diào)用策略對(duì)象的 getProxy(ClassLoader classLoader) 方法來(lái)完成操作。
總結(jié)
本文通過(guò)從 Spring 的幾個(gè)核心組件入手,試圖找出構(gòu)建 Spring 框架的骨骼架構(gòu),進(jìn)而分析 Spring 在設(shè)計(jì)的一些設(shè)計(jì)理念,是否從中找出一些好的設(shè)計(jì)思想,對(duì)我們以后程序設(shè)計(jì)能提供一些思路。接著再詳細(xì)分析了 Spring 中是如何實(shí)現(xiàn)這些理念的,以及在設(shè)計(jì)模式上是如何使用的。
通過(guò)分析 Spring 給我一個(gè)很大的啟示就是其這套設(shè)計(jì)理念其實(shí)對(duì)我們有很強(qiáng)的借鑒意義,它通過(guò)抽象復(fù)雜多變的對(duì)象,進(jìn)一步做規(guī)范,然后根據(jù)它定義的這套規(guī)范設(shè)計(jì)出一個(gè)容器,容器中構(gòu)建它們的復(fù)雜關(guān)系,其實(shí)現(xiàn)在有很多情況都可以用這種類似的處理方法。
雖然我很想把我對(duì) Spring 的想法完全闡述清楚,但是所謂“書不盡言,言不盡意。”,有什么不對(duì)或者不清楚的地方大家還是看看其源碼吧。
posted on 2010-06-21 22:54
特立獨(dú)行 閱讀(503)
評(píng)論(0) 編輯 收藏 所屬分類:
Spring框架