truevalue>property>
testInterceptorvalue>
testInterceptor2value>
list>
property>
bean>
配置上看到要設(shè)置被代理的接口,和接口的實(shí)現(xiàn)類也就是目標(biāo)類,以及攔截器也就在執(zhí)行目標(biāo)方法之前被調(diào)用,這里Spring中定義的各種各樣的攔截器,可以選擇使用。
下面看看Spring如何完成了代理以及是如何調(diào)用攔截器的。
前面提到Spring Aop也是實(shí)現(xiàn)其自身的擴(kuò)展點(diǎn)來(lái)完成這個(gè)特性的,從這個(gè)代理類可以看出它正是繼承了Factory Bean的ProxyFactoryBean,F(xiàn)actoryBean之所以特別就在它可以讓你自定義對(duì)象的創(chuàng)建 方法。當(dāng)然代理對(duì)象要通過(guò)Proxy類來(lái)動(dòng)態(tài)生成。
下面是Spring創(chuàng)建的代理對(duì)象的時(shí)序圖:

圖19.Spring代理對(duì)象的產(chǎn)生
Spring創(chuàng)建了代理對(duì)象后,當(dāng)你調(diào)用目標(biāo)對(duì)象上的方法時(shí),將都會(huì)被代理到InvocationHandler類的invoke方法中執(zhí)行,這在前面已經(jīng)解釋。在這里JdkDynamicAopProxy類實(shí)現(xiàn)了InvocationHandler接 口。
下面再看看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;