成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Spring之旅第七站:面向切面編程(AOP)

趙連江 / 891人閱讀

摘要:面向切面的本章主要內容面向切面編程的基本原理通過創(chuàng)建切面使用注解為切面注入依賴。什么是面向切面編程切面能夠幫我們模塊化橫切關注點。在使用面向切面編程時,我們仍然在一個地方定義通知功能,而無需修改受影響的類。切面切面是通知和切點的結合。

面向切面的Spring

本章主要內容:

面向切面編程的基本原理

通過POJO創(chuàng)建切面

使用@Aspect注解

為AspectJ切面注入依賴。

說明

如果你有幸能看到。

1、本文參考了《Spring 實戰(zhàn)》重點內容,參考了GitHub上的代碼

2、本文只為記錄作為以后參考,要想真正領悟Spring的強大,請看原書。

3、在一次佩服老外,國外翻譯過來的書,在GiuHub上大都有實例??磿臅r候,跟著敲一遍,效果很好。

4、代碼和筆記在這里GitHub,對你有幫助的話,歡迎點贊。

5、每個人的學習方式不一樣,找到合適自己的就行。2018,加油。

6、問候了下Java 8 In Action 的作者Mario Fusco,居然回復了。

7、Spring In Action 、Spring Boot In Action的作者Craig Walls老忙了,沒理睬。

8、知其然,也要知其所以然。

談一些個人感受

1、趕快學習Spring吧,Spring MVC 、Spring Boot 、微服務。

2、重點中的重點,學習JDK 8 Lambda,Stream,Spring 5 最低要求JDK1.8.

3、還有Netty、放棄SH吧,不然你會落伍的。

4、多看一些國外翻譯過來的書,例如 Xxx In Action 系列。權威指南系列。用Kindle~

軟件系統(tǒng)中的一些功能就像我們家里的電表一樣。則核心功能需要用到應用程序的多個地方。但是我們又不想在每個點都明確調用它。日志、安全、事務管理的確很重要。但它們是否為應用對象主動參與的行為呢?如果讓應用對象只關注與自己所針對的業(yè)務領域問題,而其他方面的問題由其他應用對象來處理,這樣不更好嗎?

在軟件開發(fā)中,散布于應用中多出功能被稱為橫切關注點(crosscutting concern)。通常來講橫切關注點從概念上是與應用的業(yè)務邏輯分離的。但往往是耦合在一起的,把這些橫切關注點與業(yè)務邏輯相分離正是面向切面編程(AOP)所要解決的問題。

依賴注入(DI)管理我們的應用對象,DI有助于應用對象之間解耦。而AOP可以實現(xiàn)橫切關注點與它們所影響的對象之間的耦合。

4.1 什么是面向切面編程

切面能夠幫我們模塊化橫切關注點。簡而言之,橫切關注點可以被描述為影響應用多處的功能。例如 安全,事務、日志等功能。

如果要重用對象的話,最常見的面向對象技術是繼承、委托、組合。但是,如果整個應用中都使用相同的基類,繼承往往會導致一個脆弱的對象體系。而使用委托可能需要委托對象進行復雜的調用。

切面提供了取代繼承和委托的另一種可選方案。在使用面向切面編程時,我們仍然在一個地方定義通知功能,而無需修改受影響的類。橫切關注點可以被模塊化為特殊的類,這些類被稱為切面(aspect). 這樣做帶來兩個好處:每個關注點都集中到一個地方,而不是分散到多處代碼中:其次,服務模塊更簡潔,因為它只包含了主要關注點(核心功能)的代碼。而次要關注的代碼被移到切面中了。

4.1.1 定義AOP術語

描述切面的常用術語有:通知(advice)、切點(pointcut)、(連接點)。

通知(advice)

通知定義了切面是什么以及何時使用。除了描述切面要完成的工作外,通知還解決了何時執(zhí)行這個工作問題。它應該在某個方法被調用之前?之后?之前和之后都調用?還是只在方法拋出異常時調用?

Spring切面可以應用5中類型的通知:

前置通知(Before):在目標方法被調用之前調用通知功能。

后置通知(After):在目標方法完成之后調用通知

返回通知(After-returning):在目標方法成功執(zhí)行之后調用通知

異常通知(After-throwing):在目標方法拋出異常后調用通知

環(huán)繞通知(Around):在被通知方法調用之前和調用之后執(zhí)行自定義的行為

連接點

我們的應用可能有數(shù)以千計的時機應用通知,這些時機被稱為連接點。連接點是在應用執(zhí)行過程中能夠插入的一個點。這個點可以是調用方法時,拋出異常時,甚至修改一個字段時。切面可以利用這些點插入到應用的正常流程之中,并添加新的行為。

切點 如果說通知定義了切面的的“什么”和“何時”,那么切點定義了“何處”。切點的定義會匹配通知所要織入的一個或多個連接點。

切面 切面是通知和切點的結合。通知和切點通過定義了切面的全部 內容——他是什么,在什么時候和在哪里完成其功能。

引入 引入允許我們向現(xiàn)有的類添加新的方法或者屬性。

織入

織入是把切面應用到目標對象并創(chuàng)建新的代理對象的過程。切面在指定的連接點被織入到目標對象。在目標對象的生命周期里有多個點可以進行織入:

編譯器:切面在目標類編譯時被織入。Aspect的織入編譯器就是以這種方式織入切面的。

類加載器:切面在目標類加載到JVM時被織入。需要特殊的類加載(Classloader),它可以在目標類被引入之前增強該目標類的字節(jié)碼(CGlib)

運行期:切面在應用運行時的某個時刻被織入。AOP會為目標對象創(chuàng)建一個代理對象

通知包含了需要用于多個應用對象的橫切關注點。連接點是程序執(zhí)行過程中能夠應用通知的所有點。切點定義了通知被應用的具體位置(在哪些連接點),其中關鍵是切點定義了哪些連接點會得到通知。

4.1.2 Spring對AOP的支持

并不是所有的AOP框架都是相同的,他們在連接點模型上可能有強弱之分。有些允許在字段修飾符級別的通知,而另一些只支持與方法調用相關的連接點。它們織入切面的方式和時機也有所不同。但是,無論如何,創(chuàng)建切點來定義切面所織入的連接點是AOP的基本功能。

Spring提供了4種類型的AOP支持:

基于代理的經典Spring AOP

純POJO切面

@AspectJ注解驅動的切面

注入式AspectJ切面

前三種都是Spirng AOP實現(xiàn)的變體,Spring AOP構建在動態(tài)代理基礎上。因此,Spring對AOP的支持局限于方法攔截。

引入了簡單的聲明式AOP與基于注解的AOP之后,Spring經典的看起來就顯得非常笨拙和過于復雜話,直接使用ProxyFactory bean 會讓人感覺厭煩。

借助于Spring的aop命名空間,我們可以將純POJO轉為切面。

Spring借鑒了AspectJ的切面,以提供注解驅動的AOP。本質上,它依然是Spring基于代理的AOP,但是編程模型幾乎與編寫成熟的AspectJ注解切面完全一致。這種AOP風格的好處在于能夠不使用XML來完成功能。

Spring所創(chuàng)建的通知都是用標準的Java類編寫的,定義通知所應用的切點通常會使用注解或在Spring配置文件里采用XML來編寫

通知帶代理類中包裹切面,Spring在運行時把切面織入到Spring所管理的bean中。代理類封裝了目標類,并攔截被通知方法的調用。再把調用轉發(fā)給真正的目標bean。當代理攔截到方法調用時,在調用目標bean方法之前,會執(zhí)行切面邏輯。直到應用需要被代理bean時,Spring才會創(chuàng)建代理對象。如果使用ApplicationContext的話,在ApplicationContext從BeanFactory中加載所有的bean的時候,Spring才會創(chuàng)建被代理的對象。因為Spirng運行時才創(chuàng)建代理對象,所以我們不需要特殊的編譯器來織入Spring AOP的切面。

Spring基于動態(tài)代理,所以Spring只支持方法連接點。方便攔截可以滿足大部分的需求。

4.2 通過切點來選擇連接點

切點用于準確定位應該在什么地方應用切面的通知。通知和切點是切面最基本的元素。

Spring僅支持AspectJ切點指示器的一個子集。Spring是基于代理的,而某些切點表達式是基于代理的AOP無關的。

Spring支持的指示器,只有execution指示器是實際執(zhí)行匹配的,而其他的指示器都是用來限制匹配的。這說明execution指示器是我們在編寫切點定義時最主要的指示器。

4.2.1編寫切點

為了闡述Spring中的切面, 我們需要有個主題來定義切面的切點。

package com.guo.cocert;
public interface Performance {
  public void perform();
}
execution(* concert.Performance.perform(..))

我們使用execution()指示器選擇Performance的perform()方法,方法表達式以"*"號開始,表明了我們不關心方法返回值的類型。然后指明了全限定類名和方法名,對于方法參數(shù)列表,我們使用了兩個點號(..)表明切點要選擇任意的perform()方法,無論該方法的入參是什么。

現(xiàn)在假設我們需要配置的切點僅匹配concert包,可以使用within()指示器

execution(* concert.Performance.perform(..)) && within(concert.*)

因為“&”在XMl中有特殊的含義,所以在Spring和XML配置中,描述切點時,可以使用and代替“&&”。

4.2.2 在切點中選擇bean

Spring引入了一個新的bean()指示器,它允許我們在切點表達式中使用bean的ID來標識bean。bean()使用bean ID 或 bean 名稱作為參數(shù)來限制切點只匹配特定的bean。

execution(* concert.Performance.perform(..)) and bean("woodsotck")

也可以這樣

execution(* concert.Performance.perform(..)) and !bean("woodsotck")

切面的通知會被編織到所有ID不為woodsotck的bean中。

4.3使用注解創(chuàng)建切面

使用注解來創(chuàng)建切面是AspectJ 5所引入的關鍵特性。

4.3.1 定義切面

如果一場演出沒有觀眾的話,那不能稱之為演出。

@AspectJ
public class Audience {

}

Audience類使用@AspectJ注解進行了標注。該注解表明Audience不僅僅是一個POJO,還是一個切面。Audience類中的方法都是使用注解來定義切面的具體行為。

@AspectJ
public class Audience {
  @Pointcut("execution(* * concern.Performance.perform(..))")
  public void performance() {};
}

在Autience中,performance()方法使用了@Pointcut注解。為@Pointcut注解設置的值是一個切點表達式,就像之前在通知注解上所設置的那樣。

需要注意的是,除了注解和沒有實際操作的performa()方法,Audience類依然是一個POJO,我們能夠像使用其他的Java類那樣調用它的方法,它的方法也能獨立的進行單元測試。與其他Java類沒有什么區(qū)別。

像其他的Java類一樣,它可以裝配為Spring中的bean

@Bean
public Audience audience() {
  return new Audience();
}

如果你就此止步的話,Audience只會是Spring容器中的一個bean。即便使用了AspectJ注解,但它并不會被視為切面,這些注解不會解析,也不會創(chuàng)建將其轉化為切面的代理。

如果你使用JavaConfig的話,可以在配置類的級別上通過使用EnableAspectJ-AutoProxy注解啟用自動代理功能。

@Configuration
@EnableAspectJAutoProxy             //啟用AspectJ自動代理
@ComponentScan
public class ConcertConfig {
  @Bean
  public Audience autidence() {     //聲明Audience bean
    return new Audience();
  }
}

假如你在Spring中使用XMl來裝配bean的話,那么需要使用Spring aop命名空間中的元素



、、、、、、、、、、、、、、、、、、、、、、、、



不管你使用JavaConfig還是XML,AspecJ自動代理都會使用@Aspect注解的bean創(chuàng)建一個代理。這個代理會圍繞著所有該切面的切點所匹配的bean。

我們需要記住的是,Spring的AspectJ自動代理僅僅使用@AspectJ作為創(chuàng)建切面的指導,切面依然是基于代理的。本質上它依然是Spring基于代理的切面。

4.3.2 創(chuàng)建環(huán)繞通知

環(huán)繞通知是最為強大的通知類型,它能夠讓你編寫的邏輯將被通知的目標方法安全包裝起來,實際上就像在一個通知方法中同時編寫前置通知和后置通知。

@AspectJ
public class Audience {
  @Pointcut("execution(* * concern.Performance.perform(..))")
  public void performance() {};
  @Around
  public void xx(Xxx jp) {
    .......
    jp.proced()
  }
}

在這里,@Around注解,表明這個xx()方法會作為performance()切點的環(huán)繞通知。

這個通知所達到的效果與之前的前置通知和后置通知是一樣的。

需要注意的是,別忘記調用proceed()方法,如果不調用這個方法,那么你的通知實際上會阻塞對被通知方法的調用,有意思的是,你可以不調用proceed方法,從而阻塞對被通知方法的反問,

4.3.4 通過注解引入新功能

一些編程語言,例如:Ruby和Groovy,有開放來的理念,它們可以不直接使用修改對象或類的定義就能夠為對象或類增加新的方法。不過Java并不是動態(tài)語言,一旦編譯完成了,就很難在為該類添加新的功能了。

如果切面能夠為現(xiàn)有的方法增加額外的功能,為什么不恩那個為一個對象增加新的方法呢?利用引入AOP的概念,切面可以為Spring bean 添加新的方法。

在Spring中,注解和自動代理提供了一種便利的方式來創(chuàng)建切面,它非常簡單,并且只設計最少的Spring配置,但是,面向注解的切面有一個明顯的不足點:你必須能夠為通知類添加注解,為了做到這一點,必須要有源碼。

4.4 在XML中聲明切面

之前,有這樣一條原則:那就是基于注解的配置要優(yōu)于Java的配置,基于Java的配置要優(yōu)于XMl的配置,但是,如果你需要聲明切面,但是又不能為通知類添加注解的時候 ,那么就必須轉向XML配置了。

在Spring的aop命名空間中,提供了多個元素用來在XML中聲明切面,

:定義AOP通知器

:定義AOP后置通知

:定義AOP返回通知

:定義AOP異常通知

:定義AOP環(huán)繞通知

:定義一個切面

:啟用@AspectJ注解

:定義一個AOP前置通知

:定義一個切點

4.4.1 聲明前置通知和后置通知

我們會使用Spring aop命名空間中的一些元素,將沒有注解的Aurience類轉為切面


           

        

        

        

        

    

第一需要注意的就是大多數(shù)AOP配置元素必須在元素的上下文中使用。

在所有的通知元素中,pointcut屬性定義了通知所應用的切點,它的值是使用AspectJ切點表達式語法所定義的切點。

在基于Aspectj注解的通知中,當發(fā)現(xiàn)在這些類型的重復時,使用@Pointcut注解來消除這些重復的內容。

如下的XMl配置展示了如何將通用的切點表達式抽取到一個切點聲明中,這樣,這個聲明就能在所有的通知元素中使用了


           
        

        

        

        

        

    

現(xiàn)在的切點是一個地方定義的,并且被多個通知元素所引用,元素定義了一個id為performance的切點,同時修改所有的通知元素,用pointcut0ref來引用這個命名切點。

4.4.2 聲明環(huán)繞通知

相比于前置通知和后置通知,環(huán)繞通知在這點上有明顯的優(yōu)勢。使用環(huán)繞通知,我們可以完成前置通知和后置通知所實現(xiàn)的相同功能,而且只需要在一個方法中實現(xiàn)。因為整個通知邏輯都是在一個方法中實現(xiàn)的。


           
        

        

    

像其他通知的XML元素一樣,指定了一個切點和一個通知方法的名字。

4.4.3 為通知傳遞參數(shù)

區(qū)別在于切點表達式中包含了一個參數(shù),這個參數(shù)傳遞到通知方法中。還有區(qū)別就是這里使用了and關鍵字

4.4.4 通過切面引入新的功能

借助于AspectJ的@DeclareParents注解為被通知的方法引入新的方法。但是AOP引入并不是Aspectj特有的。使用Spring aop命名空間中的元素,我們可以實現(xiàn)相同的功能


            
        
 
4.5 注入AspectJ切面

雖然Spring AOP能夠滿足許多應用的切面需求,但是與AspectJ相比,Spring AOP是一個功能比較弱的AOP解決方案,ASpect提供了Spring AOP 所不能支持的許多類型的切點。

Spring不能像之前那樣使用聲明來創(chuàng)建一個實例----它已經在運行時由AspectJ創(chuàng)建完成了,Spring需要通過工廠方法獲取切面的引用。然后像元素規(guī)定的那樣在該對象上執(zhí)行依賴注入

4.6 小節(jié)(重點中的重點)

AOP是面向對象編程的一個強大補充,通過AspectJ,我們現(xiàn)在可以把之前分散在應用各處的行為放入可重用的模塊中。我們顯示地聲明在何處如何應用該行為。這樣有效減少了代碼冗余,并讓我們的類關注自身的主要功能。

Spring提供了一個AOP框架,讓我們把切面插入到方法執(zhí)行的周圍?,F(xiàn)在我們已經學會了如何把通知織入前置,后置和環(huán)繞方法的調用中,以及為處理異常增加自定義行為。

關于在Spirng應用中如何使用切面 ,我們可以有多種選擇。通過使用@AspectJ注解和簡化的配置命名空間,在Spring中裝配通知和切點變得非常簡單

最后,當Spring不能滿足需求時,我們必須轉向更為強大的AspectJ。對于這些場景,我們了解了如何使用Spring為AspectJ切面注入依賴。

此時此刻,我們已經覆蓋了Spring框架的基礎知識,了解到如何配置Spring容器以及如何為Spring管理的對象應用切面,這些技術為創(chuàng)建高內聚,低耦合的應用奠定了堅實的基礎。

從下一章開始,首先看到的是如何使用Spring構建Web應用。。

期待......

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/68529.html

相關文章

  • 第一章--Spring之旅

    摘要:兩種方式來表示的應用上下文。日志,事務管理和安全這樣的系統(tǒng)服務經常融入到具有核心業(yè)務邏輯的組件中去,這些系統(tǒng)服務通過被稱為橫切關注點。容器使用管理構成應用的組件,他會創(chuàng)建相互協(xié)作的組件之間的關聯(lián)。的生命周期四俯瞰的風景線模塊,,,, 完整代碼請見:https://github.com/codercuixi...為了降低Java開發(fā)的復雜性,Spring采用了以下4種策略: 基于poj...

    pkwenda 評論0 收藏0
  • Spring之旅第一站(不得不佩服老外...)

    摘要:表示少女與緊耦合在它的構造函數(shù)中自行創(chuàng)建了。面向切面編程往往被定義為促使軟件系統(tǒng)實現(xiàn)關注點的分離一項技術系統(tǒng)由許多不同的組件組成,每個組件各負責一特定的功能。我們可以把切面想象為覆蓋在很多組件之上的一個外殼。 第1章 Spring之旅 說明 1、本文抄寫了《Spring 實戰(zhàn)》重點內容,參考了GitHub上的代碼 2、每個人的學習方式不一樣,但目的是一樣的,活學活用。最近一直在聽《我...

    thekingisalwaysluc 評論0 收藏0
  • 慕課網_《Spring入門篇》學習總結

    摘要:入門篇學習總結時間年月日星期三說明本文部分內容均來自慕課網。主要的功能是日志記錄,性能統(tǒng)計,安全控制,事務處理,異常處理等等。 《Spring入門篇》學習總結 時間:2017年1月18日星期三說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學示例源碼:https://github.com/zccodere/s...個人學習源碼:https://git...

    Ververica 評論0 收藏0
  • Spring之旅 - 3.0、3.1、4.0導引

    摘要:之旅簡化開發(fā)的使命簡化開發(fā)為了降低開發(fā)的復雜性,采取如下關鍵策略基于的輕量級和最小侵入性編程通過依賴注入和面向接口實現(xiàn)松耦合基于切面和慣例進行聲明式編程通過切面和模版減少樣式代碼依賴注入耦合性具有兩面性一方面,緊密耦合的代碼難以測試難以復 Spring之旅 簡化Java開發(fā) Spring的使命:簡化Java開發(fā) 為了降低Java開發(fā)的復雜性,采取如下關鍵策略:基于POJO的輕量級和最...

    leon 評論0 收藏0
  • Spring之旅第二站:bean、新特性。。。

    摘要:除了,還簡單介紹了對的支持,可以幫助應用將散落在各處的邏輯匯集于一處切面。當裝配的時候,這些切面能夠運行期編織起來,這樣就能呢個非常有效的賦予新功能。 第1章 Spring之旅 說明 1、本文參考了《Spring 實戰(zhàn)》重點內容,參考了GitHub上的代碼 2、每個人的學習方式不一樣,但目的是一樣的,活學活用。最近一直在聽《我們不一樣》 3、本文只為記錄作為以后參考,要想真正領悟Sp...

    luodongseu 評論0 收藏0

發(fā)表評論

0條評論

趙連江

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<