日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
對SpringAOP框架實現(xiàn)的結(jié)構(gòu)分析

本文的目標:

創(chuàng)新互聯(lián)主營沙河網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,重慶App定制開發(fā),沙河h5微信小程序開發(fā)搭建,沙河網(wǎng)站營銷推廣歡迎沙河等地區(qū)企業(yè)咨詢

從實現(xiàn)的角度來認識SpringAOP框架。

觀察的角度:

從外部接口,內(nèi)部實現(xiàn),組成部分,執(zhí)行過程四個方面來認識SpringAOP框架。

本文的風格:

首先列出AOP的基本概念;

其次介紹框架所涉及到的核心組件列表,組件之間的結(jié)構(gòu)關(guān)系圖;

然后細化結(jié)構(gòu)圖中的部分;

接下來是一個簡單的sample;

***是后記部分。

注:

1.本文的源代碼基于Spring2.x。Spring的源代碼也處于演變中,但對基礎(chǔ)代碼的影響并不大。

2.本文是對Spring IoC容器實現(xiàn)的結(jié)構(gòu)分析的姊妹帖。

正文:

Spring AOP框架涉及的基本概念介紹:

關(guān)注點(concern):一個關(guān)注點可以是一個特定的問題、概念、或是應用程序的興趣區(qū)間--總而言之,應用程序必須達到的一個目標。

核心關(guān)注點(core concern):業(yè)務功能模塊,如:存款模塊,取款模塊,轉(zhuǎn)賬模塊等,

橫切關(guān)注點(crosscutting concern):非功能性的、橫切性模塊,如:安全性管理,事務管理,性能監(jiān)控等。

方面(aspect):一個方面是對一個橫切關(guān)注點的模塊化,它將那些原本散落在各處的、用于實現(xiàn)這個關(guān)注點的代碼歸整到一處。

連接點(join point):程序執(zhí)行過程中的一點,如:

字段訪問:讀、寫實例變量;

方法調(diào)用:對方法(包括構(gòu)造方法)的調(diào)用;

異常拋出:特定的異常被拋出。

切入點(pointcut):一組連接點的總稱,用于指定某個增強應該在何時被調(diào)用。切入點常用正則表達式或別的通配符語法來描述,有些AOP實現(xiàn)技術(shù)還支持切入點的組合。

增強(advice):在特定連接點執(zhí)行的動作。很多AOP框架都以攔截器(interceptor)的形式來表現(xiàn)增強--所謂攔截器是這樣的一個

對象:當連接點被調(diào)用時,它會收到一個回調(diào)消息?;镜脑鰪娪校?/p>

前增強(BeforeAdvice):在連接點調(diào)用之前,首先調(diào)用增強;

后增強(AfterAdvice):在連接點調(diào)用之后,再調(diào)用增強,在AspectJ中,后增強又分為三種:

AfterReturningAdvice:在調(diào)用成功完成(沒有異常拋出)之后。

AfterThrowingAdvice:在拋出某種特定類型(或其子類型)的異常之后。

AfterAdvice:在連接點的任何調(diào)用之后,不管調(diào)用是否拋出異常。

環(huán)繞增強(AroundAdvice):這類增強可以完全控制執(zhí)行流程。除了完成本身的工作之外,它還需要負責主動調(diào)用連接點,促使真實的操作發(fā)生(proceed)-- 這通常是通過調(diào)用某個特定的方法來完成的。

引介(introduction):為一個現(xiàn)有的Java類或接口添加方法或字段。這種技術(shù)可以用于實現(xiàn)Java中的多繼承,或者給現(xiàn)有對象模型附加新的API。

混入繼承(mixin inheritance):一個“混入類”封裝了一組功能,這組功能可以被"混入"到現(xiàn)有的類當中,并且無須使用傳統(tǒng)的繼承手段。在AOP這里,混入是通過引介來實現(xiàn)的。在Java語言中,可以通過混入來模擬多繼承。

織入(weaving):將方面整合到完整的執(zhí)行流程(或完整的類,此時被織入的便是引介中)。

攔截器(initerceptor):很多AOP框架用它來實現(xiàn)字段和方法的攔截(interception)。隨之而來的就是在連接點(如方法攔截)處掛接一條攔截器鏈(interceptor chain),鏈條上的每個攔截器通常會調(diào)用下一個攔截器。

AOP代理(AOP proxy):即被增強(advise)的對象引用--也就是說,AOP增強將在其上執(zhí)行的這樣一個對象引用。

目標對象(target object):位于攔截器鏈末端的對象實例--這個概念只存在于那些使用了攔截機制的框架之中。

注:上述概念描述引自《Expert One-on-One J2EE Development without EJB》中第八章對AOP概念描述部分,更多精彩部分可以參閱本章的完整內(nèi)容。

上述概念已被Spring AOP框架很好的實現(xiàn),相關(guān)組件:

Advisor 組件,

Advice 組件,

Pointcut 組件,

Advised 組件,

AopProxy 組件,

AopProxyFactory 組件,

圖1.

圖1是對增強、切入點、方面、AOP代理之間依賴關(guān)系的全景圖。

增強和切入點組成一個方面,方面信息與目標對象信息被組織到Advised中,AopProxyFactory通過Advised中保存的信息生成AopProxy

對象,調(diào)用AopProxy.getProxy()方法即可獲得增強后的對象。

這里要著重了解的是不同的增強子類型,不同的切入點子類型,

對于不同的切入點子類型最重要的兩種子類型:靜態(tài)切入點,動態(tài)切入點,

靜態(tài)切入點:根據(jù)部署階段的信息選擇增強,如“攔截特定類的所有g(shù)etter方法”;

動態(tài)切入點:根據(jù)運行時的信息選擇增強,如“如果某方法的返回值為null,則將其納入某切入點”。

圖2.

圖2是對圖1中Advisor與Pointcut的實現(xiàn)細化,圖中類之間的關(guān)系直觀上有點亂,但細看下關(guān)系還是相當清晰的,

以Advisor結(jié)尾的是方面類型,以Pointcut結(jié)尾的是切入點類型,

Advisor與Pointcut的復用關(guān)系分兩類:一類是組合復用,另一類是具體繼承復用,

組合復用例子 如:RegexpMethodPointcutAdvisor 與 AbstractRegexpMethodPointcut之間的關(guān)系,

NameMatchMethodPointcutAdvisor 與 NameMatchMethodPointcut之間的關(guān)系,

具體繼承復用例子 如:StaticMethodMatcherPointcutAdvisor 與 StaticMethodMatcherPointcut 之間的關(guān)系,

DynamicMethodMatcherPointcutAdvisor 與 DynamicMethodMatcherPointcut 之間的關(guān)系,

圖3.

圖3是對圖1中生成AopProxy對象的實現(xiàn)細化,

AopProxyFactory通過AdvisedSupport提供的信息生成AopProxy對象,AopProxy對象的生成分兩類方式:一類是動態(tài)代理,另一類是字節(jié)碼增強;

需要注意的是,ProxyFactory與ProxyFactoryBean并不是功能實現(xiàn)的必要部分,主要目的為編程式使用代理提供便利的API。

#p#

下面是一個簡單的sample:

 
 
 
  1. //目標對象接口.
  2. public interface Target {
  3.     public String play(int arg);
  4. }
  5. //目標對象實現(xiàn).
  6. public class TargetImpl implements Target {
  7.     public String play(int arg) {
  8.          System.out.println("play method....");
  9.         return "[Target:]" + arg;
  10.     }
  11. }
  12. //前置增強
  13. public class MyBeforeAdvice implements MethodBeforeAdvice {
  14.     public void before(Method method, Object[] args, Object target)
  15.             throws Throwable {
  16.          System.out.println(method.getName());
  17.          System.out.println("before method!");
  18.     }
  19. }
  20. //后置增強
  21. public class MyAfterAdvice implements AfterReturningAdvice {
  22.     public void afterReturning(Object returnValue, Method method,
  23.             Object[] args, Object target) throws Throwable {
  24.          System.out.println(returnValue + ":after method"); 
  25.     }
  26. }
  27. //切入點實現(xiàn)
  28. public class MyPointcut implements Pointcut {
  29.     public ClassFilter getClassFilter() {
  30.          
  31.         return new ClassFilter() {
  32.             public boolean matches(Class arg0) {
  33.                 if (arg0 == TargetImpl.class) {
  34.                     return true;
  35.                 }
  36.                 return false;
  37.             }
  38.             
  39.         };
  40.     }
  41.     public MethodMatcher getMethodMatcher() {
  42.          
  43.         return new MethodMatcher() {
  44.             public boolean isRuntime() {
  45.                  
  46.                 return false;
  47.             }
  48.             public boolean matches(Method arg0, Class arg1) {
  49.                 
  50.                 if ("play".equals(arg0.getName())) {
  51.                     return true;
  52.                 }
  53.                 return false;
  54.             }
  55.             public boolean matches(Method arg0, Class arg1, Object[] arg2) {
  56.                 System.out.println("aaaaaa");
  57.                 if ("play".equals(arg0.getName())) {
  58.                     return true;
  59.                 }
  60.                 return false;
  61.             }
  62.             
  63.         };
  64.     }
  65. }
  66. public class Main {
  67.     public static void main(String[] args) {
  68.          Target target = new TargetImpl();   //目標對象
  69.          Advice beforeAdvice = new MyBeforeAdvice(); //增強
  70.          Pointcut pointcut = new MyPointcut(); //切入點
  71.          DefaultPointcutAdvisor dda = new DefaultPointcutAdvisor(); //切面
  72.          dda.setAdvice(beforeAdvice);
  73.          dda.setPointcut(pointcut);
  74.          
  75.          AdvisedSupport advisedSupport = new AdvisedSupport(); //提供基本的編程方式,
  76.          advisedSupport.addAdvisor(dda);
  77.          advisedSupport.addAdvice(new MyAfterAdvice());
  78.          advisedSupport.addInterface(Target.class);
  79.          advisedSupport.setTarget(target);
  80.          AopProxy aopProxy = new DefaultAopProxyFactory().createAopProxy(advisedSupport);
  81.          Target proxy = (Target)aopProxy.getProxy();
  82.          System.out.println(proxy.play(200));
  83.          
  84.          ProxyFactory proxyFactory = new ProxyFactory();  //提供便利的編程方式.
  85.          proxyFactory.addAdvisor(dda);
  86.          proxyFactory.addInterface(Target.class);
  87.          proxyFactory.setTarget(target);
  88.          Target proxy2 = (Target)proxyFactory.getProxy();
  89.          System.out.println(proxy2.play(201));
  90.          
  91.          ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean(); //提供便利的配置方式
  92.          proxyFactoryBean.addAdvisor(dda);
  93.          proxyFactoryBean.addInterface(Target.class);
  94.          proxyFactoryBean.setTarget(target);
  95.          Target proxy3 = (Target)proxyFactoryBean.getObject();
  96.          System.out.println(proxy3.play(232));
  97.     }
  98. }

注:此處為了簡單忽略了一些概念描述:

1.對引介,混入繼承沒有涉及。

2.對通知鏈的管理,如:同一切入點多個通知對象之間的執(zhí)行順序問題;

3.上述的描述是Spring AOP框架本身,所提供的使用方式是編程式,這種使用方式太過于低級,以至于我們在九成的情況下不會使用到,主流的使用方式是配置化的聲明式使用方式,將AOP與IoC結(jié)合起來使用才能發(fā)揮出***威力,ProxyFactoryBean提供了有限的聲明式使用方式,但嚴格來說它仍是編程式,因為ProxyFactoryBean是一個FactoryBean,一個FactoryBean的目標就是以編程式替換復雜的配置式,而且最重要的是它暴露的API太過低級,配置文件中bean元素的abstract屬性對配置文件的長度提供有限的幫助,自動代DefaultAdvisorAutoProxyCreator很好的隱藏了低級的API,DefaultAdvisorAutoProxyCreator是一個BeanPostProcessor,用于完成AOP框架與IoC容器的集成工作,但是這種方式依然沒有解決需要同XXXAdvisor這樣的低級API打交道的問題;

隨著spring2.x引入的xml元素 及@Aspect注解的AspectJ描述性風格的出現(xiàn),使用Spring AOP框架的使用達到完全的聲明式標準,這種風格也使得Spring 事務框架受益,從TransactionProxyFactoryBean類到xml元素 、

及@Transactional注解,

原文:http://www.iteye.com/topic/1114645

使得我們只需關(guān)注高層描述,而無需涉及低級API。

附上DefaultAdvisorAutoProxyCreator的類結(jié)構(gòu)圖:

總結(jié):

要全面理解AOP相關(guān)概念,回答下述問題是必須的。

1。AOP概念產(chǎn)生的背景,AOP所要解決的問題,AOP所涉及的概念,

2。實現(xiàn)一個AOP框架所需要注意的問題是什么,

3。不同AOP框架實現(xiàn)之間的比較,

4。AOP的一些副作用討論。


網(wǎng)頁名稱:對SpringAOP框架實現(xiàn)的結(jié)構(gòu)分析
URL鏈接:http://www.dlmjj.cn/article/dpsjopg.html