最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring AOP的使用詳解

 更新時(shí)間:2019年05月29日 11:48:29   作者:Wan QingHua  
這篇文章主要介紹了Spring AOP的使用詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

什么是AOP

AOP(Aspect Oriented Programming 面向切面編程),通過預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。AOP是OOP的延續(xù),是軟件開發(fā)中的一個(gè)熱點(diǎn),也是Spring框架中的一個(gè)重要內(nèi)容,是函數(shù)式編程的一種衍生范型。利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率。

常用于日志記錄,性能統(tǒng)計(jì),安全控制,事務(wù)處理,異常處理等等。

定義AOP術(shù)語

切面(Aspect):切面是一個(gè)關(guān)注點(diǎn)的模塊化,這個(gè)關(guān)注點(diǎn)可能是橫切多個(gè)對(duì)象;

連接點(diǎn)(Join Point):連接點(diǎn)是指在程序執(zhí)行過程中某個(gè)特定的點(diǎn),比如某方法調(diào)用的時(shí)候或者處理異常的時(shí)候;

通知(Advice):指在切面的某個(gè)特定的連接點(diǎn)上執(zhí)行的動(dòng)作。Spring切面可以應(yīng)用5中通知:

  • 前置通知(Before):在目標(biāo)方法或者說連接點(diǎn)被調(diào)用前執(zhí)行的通知;
  • 后置通知(After):指在某個(gè)連接點(diǎn)完成后執(zhí)行的通知;
  • 返回通知(After-returning):指在某個(gè)連接點(diǎn)成功執(zhí)行之后執(zhí)行的通知;
  • 異常通知(After-throwing):指在方法拋出異常后執(zhí)行的通知;
  • 環(huán)繞通知(Around):指包圍一個(gè)連接點(diǎn)通知,在被通知的方法調(diào)用之前和之后執(zhí)行自定義的方法。

切點(diǎn)(Pointcut):指匹配連接點(diǎn)的斷言。通知與一個(gè)切入點(diǎn)表達(dá)式關(guān)聯(lián),并在滿足這個(gè)切入的連接點(diǎn)上運(yùn)行,例如:當(dāng)執(zhí)行某個(gè)特定的名稱的方法。

引入(Introduction):引入也被稱為內(nèi)部類型聲明,聲明額外的方法或者某個(gè)類型的字段。

目標(biāo)對(duì)象(Target Object):目標(biāo)對(duì)象是被一個(gè)或者多個(gè)切面所通知的對(duì)象。

AOP代理(AOP Proxy):AOP代理是指AOP框架創(chuàng)建的對(duì)對(duì)象,用來實(shí)現(xiàn)切面契約(包括通知方法等功能)

織入(Wearving):指把切面連接到其他應(yīng)用出程序類型或者對(duì)象上,并創(chuàng)建一個(gè)被通知的對(duì)象?;蛘哒f形成代理對(duì)象的方法的過程。

Spring對(duì)AOP的支持

  1. 基于代理的經(jīng)典SpringAOP;
  2. 純POJO切面;
  3. @AspectJ注解驅(qū)動(dòng)的切面;
  4. 注入式AspectJ切面(適用于Spring各版本);

前三種都是SpringAOP實(shí)現(xiàn)的變體,SpringAOP構(gòu)建在動(dòng)態(tài)代理基礎(chǔ)之上,因此,Spring對(duì)AOP的支持局限于方法的攔截。

切入點(diǎn)表達(dá)式

使用SpringAOP

SpringAOP的支持必須呀導(dǎo)入spring-aspects的jar包

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>4.3.5.RELEASE</version>
</dependency>

使用注解定義切面

采用注解的方式定義切面以及通知

@Aspect
public class Audience {
  //使用@Pointcut注解聲明頻繁使用的切入點(diǎn)表達(dá)式
  @Pointcut("execution(* com.wqh.concert.Performance.perform(..))")
  public void performance(){}
  
  @Before("performance()")
  public void silenceCellPhones(){
    System.out.println("Sillencing cell phones");
  }
  @Before("performance()")
  public void takeSeats(){
    System.out.println("Task Seat");
  }
  @AfterReturning("performance()")
  public void applause(){
    System.out.println("CLAP CLAP CLAP");
  }
  @AfterThrowing("performance()")
  public void demandRefund(){
    System.out.println("Demand a Refund");
  }
}

另外需要在applicationContext.xml也就是spring的配置文件中添加配置:

<!--啟用AspectJ的自動(dòng)代理-->
<aop:aspectj-autoproxy/>
<!--聲明bean-->
<bean class="com.wqh.concert.Audience"/>

在XML中聲明切面

定義pojo類,這里只是把上面定義的注解全public class AudienceXML {

public void silenceCellPhones() {
  System.out.println("Sillencing cell phones");
}
public void takeSeats() {
  System.out.println("Task Seat");
}
public void applause() {
  System.out.println("CLAP CLAP CLAP");
}
public void demandRefund() {
  System.out.println("Demand a Refund");
}

applicationContext.xml配置

<!--聲明bean-->
<bean name="audienceXML" class="com.wqh.concert.AudienceXML"/>
<aop:config>
  <!--引入bean-->
  <aop:aspect ref="audienceXML">
    <!--定義切點(diǎn)-->
    <aop:pointcut id="perform"
           expression="execution(* com.wqh.concert.Performance.perform(..))"/>
    <!--定義通知
      method:通知,也就是具體的方法
      pointcut-ref:引用的切點(diǎn)
      pointcut:切點(diǎn)-->
    <aop:before method="silenceCellPhones"
          pointcut-ref="perform"/>
    <aop:before method="takeSeats" pointcut-ref="perform"/>
    <aop:after-returning method="applause" pointcut-ref="perform"/>
    <aop:after-throwing method="demandRefund"
              pointcut="execution(* com.wqh.concert.Performance.perform(..))"/>
  </aop:aspect>
</aop:config>

環(huán)繞通知

在springAOP中有五種通知,環(huán)繞通知是最為強(qiáng)大的通知。它能夠讓你編寫的邏輯將被通知的目標(biāo)方法完全包裝起來。實(shí)際上就像在一個(gè)通知方法中同時(shí)編寫前置通知和后置通知。
本片文章具體講解環(huán)繞通知的使用。

使用注解

使用環(huán)繞通知定義切面:

@Aspect
public class AudienceAround {
  //使用@Pointcut注解聲明頻繁使用的切入點(diǎn)表達(dá)式
  @Pointcut("execution(* com.wqh.concert.Performance.perform(..))")
  public void performance(){}
  @Around("performance()")
  public void watchPerformance(ProceedingJoinPoint joinPoint){
    try {
      System.out.println("Silencing cell phones");
      System.out.println("Taking seats");
      joinPoint.proceed();
      System.out.println("Demanding a refund");
    } catch (Throwable throwable) {
      throwable.printStackTrace();
    }
  }
}

可以看到在上面的代碼中,定義通知的時(shí)候在通知方法中添加了入?yún)ⅲ篜roceedingJoinPoint。在創(chuàng)建環(huán)繞通知的時(shí)候,這個(gè)參數(shù)是必須寫的。因?yàn)樵谛枰谕ㄖ惺褂肞roceedingJoinPoint.proceed()方法調(diào)用被通知的方法。

另外,如果忘記調(diào)用proceed()方法,那么通知實(shí)際上會(huì)阻塞對(duì)被通知方法的調(diào)用。

在XML中定義

首先去掉上面類的所有注解:這里為了區(qū)別就重新創(chuàng)建一個(gè)類

public class AudienceAroundXML {
  public void watchPerformance(ProceedingJoinPoint joinPoint){
    try {
      System.out.println("Silencing cell phones");
      System.out.println("Taking seats");
      joinPoint.proceed();
      System.out.println("Demanding a refund");
    } catch (Throwable throwable) {
      throwable.printStackTrace();
    }
  }
}

配置:

<!--聲明bean-->
<bean name="audienceAroundXML" class="com.wqh.concert.AudienceAroundXML"/>
 <!--配置切面及通知-->
<aop:config>
  <aop:aspect ref="audienceAroundXML">
    <aop:pointcut id="performance"
           expression="execution(* com.wqh.concert.Performance.perform(..))"/>
    <aop:around method="watchPerformance" pointcut-ref="performance"/>
  </aop:aspect>
</aop:config>

處理通知中的參數(shù)

Spring借助AspectJ的切點(diǎn)表達(dá)式語言來定義Spring切面

在spring中嘗試使用其他指示器時(shí),會(huì)拋出IllegalArgument-Exception異常。

如上的這些指示器,只有exception指示器是實(shí)際執(zhí)行匹配的,而其他都是用來限制匹配的。

切面表達(dá)式分析

帶參數(shù)的切點(diǎn)表達(dá)式分解

在該切點(diǎn)表達(dá)式中使用了args(trackNumber)限定符。表示傳遞給playTrack()方法的int類型參數(shù)也會(huì)傳遞到通知中去。參數(shù)名trackNumber也與切點(diǎn)方法簽名中的參數(shù)相匹配。

創(chuàng)建切面

@Aspect
public class TrackCounter {
  @Pointcut("execution(* com.wqh.aop.CompactDisc.playTrack(int))&&args(trackNumber)")
  public void trackPlayder(int trackNumber){}
  @Before("trackPlayder(trackNumber)")
  public void countTrack(int trackNumber) {
    System.out.println("前置通知:targetNumber=" + trackNumber);
  }
}

連接點(diǎn)類

@Service
public class CompactDisc {
  public void playTrack(int trackNumber){
    System.out.println("trackNumber =" + trackNumber);
  }
}

XML配置

<!--啟用AspectJ的自動(dòng)代理-->
<aop:aspectj-autoproxy/>
<!--聲明bean-->
 <bean class="com.wqh.aop.TrackCounter"/>
 <!--自動(dòng)掃描包下的類-->
<context:component-scan base-package="com.wqh.aop"/>

測(cè)試

@Test
public void testT(){
  ApplicationContext applicationContext =
      new ClassPathXmlApplicationContext(
          new String[]{"classpath:/spring/applicationContext.xml"});
  CompactDisc compactDisc = (CompactDisc) applicationContext.getBean("compactDisc");
  compactDisc.playTrack(12);
}

上面給指定方法傳入的參數(shù)是12,在通知中獲取到了該參數(shù)

另外:在xml中配置切面來處理通知中的參數(shù),其實(shí)也差不多,只是把切點(diǎn)表達(dá)式放到了XML配置文件中。

給類添加新的功能

引入Spring實(shí)戰(zhàn)中的知識(shí)

在SpringAOP中,我們可以為Bean引入新的方法。代理攔截器調(diào)用并委托給實(shí)現(xiàn)該方法的其他對(duì)象。

當(dāng)引入接口的方法被調(diào)用時(shí),代理會(huì)把此調(diào)用委托給實(shí)現(xiàn)了新接口的某給其他對(duì)象。

使用注解方式引入

代碼
首先是連接點(diǎn)的接口及其實(shí)現(xiàn)類

public interface Person {
  void say();
}
public class ChinesePerson implements Person {
  @Override
  public void say() {
    System.out.println("說中文");
  }
}

創(chuàng)建需要添加的功能,這里個(gè)人類擴(kuò)展一個(gè)吃的功能

public interface Food {
  void eat();
}
public class ChineseFood implements Food {
  @Override
  public void eat() {
    System.out.println("吃中餐");
  }
}

編寫切面

@Aspect
public class addFuction {
  @DeclareParents(value = "com.wqh.addfunction.Person+",defaultImpl = ChineseFood.class)
  public static Food food;
}

注意這里的表達(dá)式使用的式@DeclareParents注解;該注解所標(biāo)注的靜態(tài)屬性指明了要引入的接口。

注解中使用的value屬性指定哪種類型的bean要引入該接口,這里Person后后面的“+”號(hào)表示所有子類型,而不是該類的本身。defaultImpl,指定了為引入功能提供實(shí)現(xiàn)的類。

使用XML配置bean:

<!--啟用AspectJ的自動(dòng)代理-->
<aop:aspectj-autoproxy/>
<!--聲明bean-->
<bean class="com.wqh.addfunction.addFuction"/>
<bean name="chinesePerson" class="com.wqh.addfunction.ChinesePerson"/>

測(cè)試

@Test
public void testAdd(){
  ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
      "classpath:spring/applicationContext.xml");
  Person person = (Person) applicationContext.getBean("chinesePerson");
  person.say();
  //這里可以將chinesePerson bean轉(zhuǎn)換為Food類,所以添加成功
  Food food = (Food) applicationContext.getBean("chinesePerson");
  food.eat();
}

在XML中引入

首先將上面的addFuction注解全部刪除,其他不變;然后在xml中添加相應(yīng)的配置:

<!--啟用AspectJ的自動(dòng)代理-->
<aop:aspectj-autoproxy/>
<!--聲明bean-->
<bean name="chinesePerson" class="com.wqh.addfunction.ChinesePerson"/>
 <aop:config>
   <aop:aspect>
     <aop:declare-parents types-matching="com.wqh.addfunction.Person+"
               implement-interface="com.wqh.addfunction.Food"
     default-impl="com.wqh.addfunction.ChineseFood"/>
   </aop:aspect>
 </aop:config>

這里的types-matching與上面的vale作用一樣;

default-impl與defaultImpl作用一樣,這也可以使用delegate-ref;當(dāng)然如果使用delegate-ref則是要引用SpringBean;

implement-interface則是要引入的接口

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Eclipse中實(shí)現(xiàn)JS代碼提示功能(圖文教程)

    Eclipse中實(shí)現(xiàn)JS代碼提示功能(圖文教程)

    本文通過圖文并茂的形式給大家介紹了Eclipse中實(shí)現(xiàn)JS代碼提示功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-11-11
  • SpringSecurity 自定義表單登錄的實(shí)現(xiàn)

    SpringSecurity 自定義表單登錄的實(shí)現(xiàn)

    這篇文章主要介紹了SpringSecurity 自定義表單登錄的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • 基于Java隨機(jī)生成手機(jī)短信驗(yàn)證碼的實(shí)例代碼

    基于Java隨機(jī)生成手機(jī)短信驗(yàn)證碼的實(shí)例代碼

    這篇文章主要介紹了Java隨機(jī)生成手機(jī)短信驗(yàn)證碼的實(shí)例代碼,代碼分為哦簡(jiǎn)單版和復(fù)雜版,需要的朋友可以參考下
    2019-04-04
  • Java實(shí)現(xiàn)在正則表達(dá)式中控制大小寫的方法

    Java實(shí)現(xiàn)在正則表達(dá)式中控制大小寫的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)在正則表達(dá)式中控制大小寫的方法,結(jié)合實(shí)例形式分析了java正則表達(dá)式中傳遞控制參數(shù)的功能與相關(guān)操作技巧,需要的朋友可以參考下
    2017-04-04
  • JavaCV實(shí)現(xiàn)人臉檢測(cè)功能

    JavaCV實(shí)現(xiàn)人臉檢測(cè)功能

    這篇文章主要為大家詳細(xì)介紹了JavaCV實(shí)現(xiàn)人臉檢測(cè)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • 深入了解Java 腳本化api編程

    深入了解Java 腳本化api編程

    Java 腳本 API 是一種獨(dú)立于框架的腳本語言,使用來自于Java代碼的腳本引擎 ??梢允褂肑ava語言編寫定制/可擴(kuò)展的應(yīng)用程序并將自定義腳本語言選擇留給最終用戶 。下面我們來詳細(xì)了解一下吧
    2019-06-06
  • JVM內(nèi)存模型/內(nèi)存空間:運(yùn)行時(shí)數(shù)據(jù)區(qū)

    JVM內(nèi)存模型/內(nèi)存空間:運(yùn)行時(shí)數(shù)據(jù)區(qū)

    這篇文章主要介紹了JVM內(nèi)存模型/內(nèi)存空間的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java虛擬機(jī),感興趣的朋友可以了解詳細(xì),希望能夠給你帶來幫助
    2021-08-08
  • IDEA配置Maven的超詳細(xì)步驟

    IDEA配置Maven的超詳細(xì)步驟

    Maven是一個(gè)能使我們的java程序開發(fā)節(jié)省時(shí)間和精力,是開發(fā)變得相對(duì)簡(jiǎn)單,還能使開發(fā)規(guī)范化的工具,下面這篇文章主要給大家介紹了關(guān)于IDEA配置Maven的超詳細(xì)步驟,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • Java synchronized偏向鎖的概念與使用

    Java synchronized偏向鎖的概念與使用

    因?yàn)樵谖覀儗懙某绦虍?dāng)中可能會(huì)經(jīng)常使用到synchronized關(guān)鍵字,因此JVM對(duì)synchronized做出了很多優(yōu)化,而在本篇文章當(dāng)中我們將仔細(xì)介紹JVM對(duì)synchronized的偏向鎖的細(xì)節(jié)
    2023-02-02
  • java 中模擬TCP傳輸?shù)目蛻舳撕头?wù)端實(shí)例詳解

    java 中模擬TCP傳輸?shù)目蛻舳撕头?wù)端實(shí)例詳解

    這篇文章主要介紹了java 中模擬TCP傳輸?shù)目蛻舳撕头?wù)端實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-03-03

最新評(píng)論

翁牛特旗| 镇巴县| 洪湖市| 龙山县| 上犹县| 奎屯市| 巩义市| 澳门| 方正县| 滨海县| 洛浦县| 灵丘县| 浮梁县| 通山县| 璧山县| 青河县| 右玉县| 朔州市| 苏尼特右旗| 大新县| 石渠县| 柳江县| 潜江市| 太湖县| 清远市| 疏附县| 宿迁市| 淮北市| 樟树市| 天门市| 若尔盖县| 陵川县| 刚察县| 海淀区| 饶河县| 原阳县| 郑州市| 德清县| 灵石县| 手游| 云林县|