自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

對(duì)Spring AOP框架實(shí)現(xiàn)的結(jié)構(gòu)分析

開發(fā) 后端
本文主要目標(biāo)是從實(shí)現(xiàn)的角度來認(rèn)識(shí)SpringAOP框架。首先列出AOP的基本概念;其次介紹框架所涉及到的核心組件列表,組件之間的結(jié)構(gòu)關(guān)系圖;然后細(xì)化結(jié)構(gòu)圖中的部分;接下來是一個(gè)簡單的sample。

本文的目標(biāo):

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

觀察的角度:

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

本文的風(fēng)格:

首先列出AOP的基本概念;

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

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

接下來是一個(gè)簡單的sample;

***是后記部分。

注:

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

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

正文:

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

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

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

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

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

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

字段訪問:讀、寫實(shí)例變量;

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

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

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

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

對(duì)象:當(dāng)連接點(diǎn)被調(diào)用時(shí),它會(huì)收到一個(gè)回調(diào)消息?;镜脑鰪?qiáng)有:

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

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

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

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

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

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

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

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

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

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

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

目標(biāo)對(duì)象(target object):位于攔截器鏈末端的對(duì)象實(shí)例--這個(gè)概念只存在于那些使用了攔截機(jī)制的框架之中。

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

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

Advisor 組件,

Advice 組件,

Pointcut 組件,

Advised 組件,

AopProxy 組件,

AopProxyFactory 組件,

圖1.

 

 

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

增強(qiáng)和切入點(diǎn)組成一個(gè)方面,方面信息與目標(biāo)對(duì)象信息被組織到Advised中,AopProxyFactory通過Advised中保存的信息生成AopProxy

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

這里要著重了解的是不同的增強(qiáng)子類型,不同的切入點(diǎn)子類型,

對(duì)于不同的切入點(diǎn)子類型最重要的兩種子類型:靜態(tài)切入點(diǎn),動(dòng)態(tài)切入點(diǎn),

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

動(dòng)態(tài)切入點(diǎn):根據(jù)運(yùn)行時(shí)的信息選擇增強(qiáng),如“如果某方法的返回值為null,則將其納入某切入點(diǎn)”。

圖2.

 

 

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

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

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

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

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

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

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

圖3.

 

 

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

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

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

#p#

下面是一個(gè)簡單的sample:

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

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

1.對(duì)引介,混入繼承沒有涉及。

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

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

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

 

及@Transactional注解,

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

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

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

 

 

總結(jié):

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

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

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

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

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

責(zé)任編輯:陳貽新 來源: H_eaven
相關(guān)推薦

2022-06-07 07:58:45

SpringSpring AOP

2009-09-03 15:38:54

C#實(shí)現(xiàn)AOP微型框架

2009-09-29 10:00:40

Spring AOP框

2024-11-04 16:29:19

2022-06-08 08:04:28

Springservicerepository

2019-05-10 10:50:04

Spring AOPJDK動(dòng)態(tài)代理CGLIB動(dòng)態(tài)代理

2021-05-06 18:17:52

SpringAOP理解

2011-05-18 09:47:39

spring

2011-04-26 09:33:04

SpringAOP

2012-09-27 09:47:43

SpringJava面向?qū)ο?/a>

2012-09-28 10:20:14

IBMdw

2016-12-26 10:29:01

Spring框架結(jié)構(gòu)

2009-09-03 15:03:27

C#實(shí)現(xiàn)AOP微型框架

2020-08-17 08:20:16

iOSAOP框架

2022-02-08 17:07:54

Spring BooSpring Aop日志記錄

2015-05-06 10:05:22

javajava框架spring aop

2009-06-19 13:28:30

Spring AOPSpring 2.0

2023-11-27 08:17:05

SpringJava

2015-03-02 14:00:54

2009-06-22 10:41:34

Spring.AOP
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)