中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何進行Spring AOP框架實現的結構分析

發布時間:2021-10-27 10:48:37 來源:億速云 閱讀:136 作者:柒染 欄目:編程語言

如何進行Spring AOP框架實現的結構分析,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

從實現的角度來認識SpringAOP框架。

觀察的角度:

從外部接口,內部實現,組成部分,執行過程四個方面來認識SpringAOP框架。

本文的風格:

首先列出AOP的基本概念;

其次介紹框架所涉及到的核心組件列表,組件之間的結構關系圖;

然后細化結構圖中的部分;

接下來是一個簡單的sample;

***是后記部分。

注:

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

2.本文是對Spring IoC容器實現的結構分析的姊妹帖。

正文:

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

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

核心關注點(core concern):業務功能模塊,如:存款模塊,取款模塊,轉賬模塊等,

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

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

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

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

方法調用:對方法(包括構造方法)的調用;

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

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

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

對象:當連接點被調用時,它會收到一個回調消息。基本的增強有:

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

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

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

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

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

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

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

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

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

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

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

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

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

上述概念已被Spring AOP框架很好的實現,相關組件:

Advisor 組件,

Advice 組件,

Pointcut 組件,

Advised 組件,

AopProxy 組件,

AopProxyFactory 組件,

圖1.

如何進行Spring AOP框架實現的結構分析

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

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

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

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

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

靜態切入點:根據部署階段的信息選擇增強,如“攔截特定類的所有getter方法”;

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

圖2.

如何進行Spring AOP框架實現的結構分析

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

以Advisor結尾的是方面類型,以Pointcut結尾的是切入點類型,

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

組合復用例子 如:RegexpMethodPointcutAdvisor 與 AbstractRegexpMethodPointcut之間的關系,

NameMatchMethodPointcutAdvisor 與 NameMatchMethodPointcut之間的關系,

具體繼承復用例子 如:StaticMethodMatcherPointcutAdvisor 與 StaticMethodMatcherPointcut 之間的關系,

DynamicMethodMatcherPointcutAdvisor 與 DynamicMethodMatcherPointcut 之間的關系,

圖3.

如何進行Spring AOP框架實現的結構分析

圖3是對圖1中生成AopProxy對象的實現細化,

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

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

下面是一個簡單的sample:

//目標對象接口.  public interface Target {      public String play(int arg);  }  //目標對象實現.  public class TargetImpl implements Target {       public String play(int arg) {           System.out.println("play method....");          return "[Target:]" + arg;      }  }  //前置增強  public class MyBeforeAdvice implements MethodBeforeAdvice {      public void before(Method method, Object[] args, Object target)              throws Throwable {           System.out.println(method.getName());           System.out.println("before method!");      }  }  //后置增強  public class MyAfterAdvice implements AfterReturningAdvice {      public void afterReturning(Object returnValue, Method method,              Object[] args, Object target) throws Throwable {           System.out.println(returnValue + ":after method");       }  }  //切入點實現  public class MyPointcut implements Pointcut {       public ClassFilter getClassFilter() {                     return new ClassFilter() {               public boolean matches(Class arg0) {                  if (arg0 == TargetImpl.class) {                      return true;                  }                  return false;              }                        };      }       public MethodMatcher getMethodMatcher() {                     return new MethodMatcher() {               public boolean isRuntime() {                                     return false;              }               public boolean matches(Method arg0, Class arg1) {                                    if ("play".equals(arg0.getName())) {                      return true;                  }                  return false;              }               public boolean matches(Method arg0, Class arg1, Object[] arg2) {                  System.out.println("aaaaaa");                  if ("play".equals(arg0.getName())) {                      return true;                  }                  return false;              }                        };      }   }  public class Main {      public static void main(String[] args) {           Target target = new TargetImpl();   //目標對象           Advice beforeAdvice = new MyBeforeAdvice(); //增強           Pointcut pointcut = new MyPointcut(); //切入點           DefaultPointcutAdvisor dda = new DefaultPointcutAdvisor(); //切面           dda.setAdvice(beforeAdvice);           dda.setPointcut(pointcut);                      AdvisedSupport advisedSupport = new AdvisedSupport(); //提供基本的編程方式,           advisedSupport.addAdvisor(dda);           advisedSupport.addAdvice(new MyAfterAdvice());           advisedSupport.addInterface(Target.class);           advisedSupport.setTarget(target);           AopProxy aopProxy = new DefaultAopProxyFactory().createAopProxy(advisedSupport);           Target proxy = (Target)aopProxy.getProxy();           System.out.println(proxy.play(200));                      ProxyFactory proxyFactory = new ProxyFactory();  //提供便利的編程方式.           proxyFactory.addAdvisor(dda);           proxyFactory.addInterface(Target.class);           proxyFactory.setTarget(target);           Target proxy2 = (Target)proxyFactory.getProxy();           System.out.println(proxy2.play(201));                      ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean(); //提供便利的配置方式           proxyFactoryBean.addAdvisor(dda);           proxyFactoryBean.addInterface(Target.class);           proxyFactoryBean.setTarget(target);           Target proxy3 = (Target)proxyFactoryBean.getObject();           System.out.println(proxy3.play(232));      }  }

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

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

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

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

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

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

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

附上DefaultAdvisorAutoProxyCreator的類結構圖:

如何進行Spring AOP框架實現的結構分析

總結:

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

1。AOP概念產生的背景,AOP所要解決的問題,AOP所涉及的概念,

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

3。不同AOP框架實現之間的比較,

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

看完上述內容,你們掌握如何進行Spring AOP框架實現的結構分析的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

平凉市| 长汀县| 遂宁市| 河间市| 莱西市| 民县| 沅江市| 江陵县| 彝良县| 舞阳县| 双峰县| 嵊泗县| 保德县| 云安县| 杭州市| 类乌齐县| 辽阳市| 望谟县| 衡水市| 清丰县| 子长县| 永丰县| 彭山县| 靖远县| 潜山县| 开封县| 三亚市| 海宁市| 阜阳市| 馆陶县| 青浦区| 新绛县| 保德县| 九龙县| 乐平市| 临朐县| 瓦房店市| 福清市| 河西区| 阳东县| 龙口市|