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

Spring AOP AspectJ使用及配置過程解析

 更新時(shí)間:2020年01月13日 14:35:14   投稿:yaominghui  
這篇文章主要介紹了Spring AOP AspectJ使用及配置過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

這篇文章主要介紹了Spring AOP AspectJ使用及配置過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

AspectJ是一個(gè)基于Java語言的AOP框架,Spring2.0以后新增了對(duì)AspectJ切點(diǎn)表達(dá)式支持。因?yàn)镾pring1.0的時(shí)候Aspectj還未出現(xiàn);

AspectJ1.5中新增了對(duì)注解的支持,允許直接在Bean類中定義切面。新版本的Spring框架建
議我們都使用AspectJ方式來開發(fā)AOP,并提供了非常靈活且強(qiáng)大的切點(diǎn)表達(dá)式 ;

當(dāng)然無論使用Spring自己的AOP還是AspectJ相關(guān)的概念都是相同的;

注解配置

依賴導(dǎo)入:

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

通知類型

  • @AspectJ提供的通知類型:
  • @Before 前置通知 在原始方法執(zhí)行前執(zhí)行
  • @AfterReturning 后置通知 在原始方法執(zhí)行前執(zhí)行
  • @Around 環(huán)繞通知 徹底攔截原始方法的執(zhí)行,執(zhí)行前后都可以增加邏輯,也可以不執(zhí)行原始方法
  • @AfterThrowing拋出通知,執(zhí)行原始方法出現(xiàn)異常時(shí)執(zhí)行
  • @After 最終final通知,不管是否異常,原始方法調(diào)用后都會(huì)執(zhí)行
  • @DeclareParents 引介通知,相當(dāng)于IntroductionInterceptor (了解即可)

定義切點(diǎn)

通過execution函數(shù)來定義切點(diǎn)

語法:execution(訪問修飾符 返回類型 方法名 參數(shù) 異常)

表達(dá)式示例:

  • 匹配所有類public方法:execution(public * *(..))第一個(gè)*表示返回值 ..表示任意個(gè)任意類型參數(shù)
  • 匹配指定包下所有方法: execution(* cn.xxx.dao.*(..)) 第一個(gè)想*表示忽略權(quán)限和返回值類型
  • 匹配指定包下所有方法:execution(* cn.xxx.dao..*(..))包含子包
  • 匹配指定類所有方法: execution(* cn.xxx.service.UserService.*(..))
  • 匹配實(shí)現(xiàn)特定接口所有類方法 : execution(* cn.xxx.dao.GenericDAO+.*(..))
  • 匹配所有save開頭的方法: execution(* save*(..))

前置通知

pom依賴:

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.2.2.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.2.2.RELEASE</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.2.2.RELEASE</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

xml需要添加aop名稱空間及xsd:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--  啟用aspectj  -->
  <aop:aspectj-autoproxy/>
<!--  目標(biāo)-->
  <bean id="personDao" class="com.yh.demo1.PersonDao"/>
<!--  切面-->
  <bean class="com.yh.demo1.MyAspect"/>
</beans>

test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test1 {
  @Autowired
  PersonDao personDao;

  @Test
  public void test(){
    personDao.delete();
    personDao.update();
  }
}

切面類:

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class MyAspect {
   //表示PersonDao下所有方法都作為切點(diǎn)
  @Before(value = "execution(* com.yh.demo1.PersonDao.*(..))")
  public void beforeAdvice(){
    System.out.println("before code run.....");
  }
}

當(dāng)我們需要獲取切點(diǎn)信息(被增強(qiáng)的代碼)時(shí),可以在通知添加參數(shù),想下面這樣

@Aspect
public class MyAspect {
  @Before(value = "execution(* com.yh.demo1.PersonDao.*(..))")
  public void beforeAdvice2(JoinPoint point){
    System.out.println("before code run2....." + point);
  }
}

后置通知:

//當(dāng)需要獲取原始方法的返回值時(shí)可以在注解中添加returning參數(shù)來指定參數(shù)名 Aspectj會(huì)自動(dòng)將返回值放到參數(shù)中
@AfterReturning(value = "execution(* com.yh.demo1.PersonDao.delete(..))",returning = "result")
public void afterAdvice(Object result){
  System.out.println("刪除方法執(zhí)行后 .....  返回值為:"+ result);
}

后置通知可以獲取目標(biāo)方法的返回值

環(huán)繞通知:

@Around(value = "execution(* com.yh.demo1.PersonDao.insert(..))")
public void aroundAdvice(ProceedingJoinPoint point) throws Throwable {
  //code............
  System.out.println("環(huán)繞前置..");

  //執(zhí)行原始方法 __當(dāng)需要獲取返回值時(shí)可以聲明變量接收
  Object result = point.proceed();
  System.out.println("原始方法返回值: "+result);
  //code............
  System.out.println("環(huán)繞后置..");
}

環(huán)繞通知與其他通知最大的區(qū)別在于環(huán)繞通知可以控制是否調(diào)用原始方法

注意:參數(shù)類型必須為ProceedingJoinPoint,否則 無法執(zhí)行原始方法,

異常通知

@AfterThrowing(value = "execution(* com.yh.demo1.PersonDao.save(..))",throwing = "e")
public void exceptionHandler(JoinPoint point,Exception e){
  System.out.println(point + " 方法出現(xiàn)"+e.getMessage()+"異常");
}

當(dāng)方法中出現(xiàn)時(shí)才會(huì)執(zhí)行該通知,若需要獲取異常信息,可在注解中添加throwing指定參數(shù)名稱

我們可以使用環(huán)繞+異常通知來處理數(shù)據(jù)庫(kù)事務(wù),在環(huán)繞中開啟事務(wù)以及提交事務(wù),異常通知中回滾事務(wù),當(dāng)然Spring已經(jīng)對(duì)事務(wù)進(jìn)行了封裝不需要自己寫

最終通知

@After(value = "execution(* *delete(..))")
public void afterRun(){
  System.out.println("最終");
}

最終通知叫做after 即調(diào)用原始方法之后執(zhí)行無論原始方法中是否出現(xiàn)異常

而后置叫做afterReturning表示在成功返回后才會(huì)執(zhí)行執(zhí)行

帶有邏輯符的表達(dá)式:
在表達(dá)式中可以使用戶邏輯操運(yùn)算符,與&& 或|| 非!

示例:

/*
execution(* cn.xxx.service.UserDao.insert(..))||execution(* cn.xxx.service.UserDao.delete(..))

execution(* cn.xxx.service.UserDao.*nsert(..))&&execution(* cn.xxx.service.UserDao.inser*(..))

!execution(* cn.xxx.service.UserDao.insert(..))
*/
2|4切點(diǎn)命名

切點(diǎn)命名

假設(shè)有多個(gè)通知應(yīng)用在同一個(gè)切點(diǎn)上時(shí),我們需要重復(fù)編寫execution表達(dá)式,且后續(xù)要修改切點(diǎn)時(shí)則多個(gè)通知都需要修改,維護(hù)起來非常麻煩,我們可以通過給切點(diǎn)指定名稱從而完成對(duì)切點(diǎn)的重復(fù)使用和統(tǒng)一操作,以提高開發(fā)維護(hù)效率;

//定義命名切點(diǎn) 方法名稱即切點(diǎn)名稱
@Pointcut(value = "execution(* com.yh.demo1.PersonDao.save(..))")
private void savePointcut(){}

@Pointcut(value = "execution(* com.yh.demo1.PersonDao.delete(..))")
private void deletePointcut(){}

多個(gè)通知應(yīng)用到同一個(gè)切點(diǎn):

//使用命名切點(diǎn)
@Before(value = "savePointcut()")
public void beforeAdvice(){
  System.out.println("before code run.....");
}
//使用命名切點(diǎn)
@Around(value = "savePointcut()")
public void beforeAdvice2(ProceedingJoinPoint point) throws Throwable {
  System.out.println("環(huán)繞前");
  point.proceed();
  System.out.println("環(huán)繞后");

一個(gè)通知應(yīng)用到多個(gè)切點(diǎn)

//同一個(gè)通知對(duì)應(yīng)多個(gè)切點(diǎn)
@After(value = "savePointcut()||deletePointcut()")
public void afterAdvice(){
  System.out.println("after code run.....");
}

XML配置

XML配置所需的jar 以及各個(gè)對(duì)象之間的依賴關(guān)以及表達(dá)式的寫法都是一樣的,僅僅是換種方式來寫而已;

xml:

    <!--目標(biāo)-->
  <bean id="studentDao" class="com.yh.demo2.StudentDao"/>
    <!--通知-->
  <bean id="advices" class="com.yh.demo2.XMLAdvice"/>

    <!--織入信息-->
  <aop:config>
        <!--切點(diǎn)定義-->
    <aop:pointcut id="select" expression="execution(* com.yh.demo2.StudentDao.select(..))"/>
        <!--切面定義-->
    <aop:aspect ref="advices">
      <aop:before method="before" pointcut-ref="select"/>
      <aop:after-returning method="afterReturning" pointcut-ref="select" returning="result"/>
      <aop:after method="after" pointcut-ref="select" />
      <aop:after-throwing method="exception" pointcut-ref="select" throwing="e"/>
      <aop:around method="around" pointcut-ref="select"/>
    </aop:aspect>
   
    <!--入侵式通知 即通知需要實(shí)現(xiàn)指定接口 兩種不能同時(shí)使用 -->
    <aop:advisor advice-ref="advice2" pointcut-ref="select"/>
  </aop:config>
 <!--入侵式通知Bean-->
 <bean id="advice2" class="com.yh.demo2.XMLAdvice2"/>

通知類:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.JoinPoint;

public class XMLAdvice {
  public void before(JoinPoint pointcut){ System.out.println("前置通知 切點(diǎn):"+pointcut); }

  public void afterReturning(JoinPoint point,Object result){
    System.out.println("后置通知 切點(diǎn):"+point);
  }

  public void after(JoinPoint point){ System.out.println("最終通知 切點(diǎn):"+point); }

  public void exception(JoinPoint point,Throwable e){
    System.out.println("異常通知: " + e+"切點(diǎn):"+point);
  }

  public void around(ProceedingJoinPoint point) throws Throwable {
    System.out.println("環(huán)繞前");
    point.proceed();
    System.out.println("環(huán)繞后");
  }
}

你會(huì)發(fā)現(xiàn) ,無論是XML還是注解都不需要手動(dòng)指定代理,以及目標(biāo)對(duì)象,Aspectj會(huì)從切點(diǎn)中獲取目標(biāo)對(duì)象信息并自動(dòng)創(chuàng)建代理;

AspectJ是目前更流行的方式,具體采用XML還是注解需要根據(jù)項(xiàng)目具體情況,小組協(xié)作開發(fā)推薦xml;

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

相關(guān)文章

  • 深入C++ typedef的用法總結(jié)(必看)

    深入C++ typedef的用法總結(jié)(必看)

    本篇文章是對(duì)C++中typedef的用法進(jìn)行了詳細(xì)的總結(jié)分析,需要的朋友參考下
    2013-05-05
  • SpringCloud?hystrix斷路器與局部降級(jí)全面介紹

    SpringCloud?hystrix斷路器與局部降級(jí)全面介紹

    什么是服務(wù)降級(jí)?當(dāng)服務(wù)器壓力劇增的情況下,根據(jù)實(shí)際業(yè)務(wù)情況及流量,對(duì)一些服務(wù)和頁面有策略的不處理或換種簡(jiǎn)單的方式處理,從而釋放服務(wù)器資源以保證核心交易正常運(yùn)作或高效運(yùn)作
    2022-10-10
  • Redis緩存策略超詳細(xì)講解

    Redis緩存策略超詳細(xì)講解

    實(shí)際開發(fā)中緩存處理是必須的,不可能我們每次客戶端去請(qǐng)求一次服務(wù)器,服務(wù)器每次都要去數(shù)據(jù)庫(kù)中進(jìn)行查找,為什么要使用緩存?說到底是為了提高系統(tǒng)的運(yùn)行速度
    2022-09-09
  • Springmvc數(shù)據(jù)回顯實(shí)現(xiàn)原理實(shí)例解析

    Springmvc數(shù)據(jù)回顯實(shí)現(xiàn)原理實(shí)例解析

    這篇文章主要介紹了Springmvc數(shù)據(jù)回顯實(shí)現(xiàn)原理實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • java基礎(chǔ)二叉搜索樹圖文詳解

    java基礎(chǔ)二叉搜索樹圖文詳解

    二叉樹是一種非常重要的數(shù)據(jù)結(jié)構(gòu),它同時(shí)具有數(shù)組和鏈表各自的特點(diǎn),下面這篇文章主要給大家介紹了關(guān)于java基礎(chǔ)二叉搜索樹的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-03-03
  • 手?jǐn)]一個(gè) spring-boot-starter的全過程

    手?jǐn)]一個(gè) spring-boot-starter的全過程

    這篇文章主要介紹了手?jǐn)]一個(gè) spring-boot-starter的全過程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • SpringBoot項(xiàng)目實(shí)現(xiàn)統(tǒng)一異常處理的最佳方案

    SpringBoot項(xiàng)目實(shí)現(xiàn)統(tǒng)一異常處理的最佳方案

    在前后端分離的項(xiàng)目開發(fā)過程中,我們通常會(huì)對(duì)數(shù)據(jù)返回格式進(jìn)行統(tǒng)一的處理,這樣可以方便前端人員取數(shù)據(jù),后端發(fā)生異常時(shí)同樣會(huì)使用此格式將異常信息返回給前端,本文介紹了如何在SpringBoot項(xiàng)目中實(shí)現(xiàn)統(tǒng)一異常處理,如有錯(cuò)誤,還望批評(píng)指正
    2024-02-02
  • SpringBoot生成PDF的方法

    SpringBoot生成PDF的方法

    生成PDF是一種常見的需求,本文主要介紹了SpringBoot生成PDF的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • 使用spring的restTemplate注意點(diǎn)

    使用spring的restTemplate注意點(diǎn)

    這篇文章主要介紹了使用spring的restTemplate注意點(diǎn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java SpringMVC框架開發(fā)之?dāng)?shù)據(jù)導(dǎo)出Excel文件格式實(shí)例詳解

    Java SpringMVC框架開發(fā)之?dāng)?shù)據(jù)導(dǎo)出Excel文件格式實(shí)例詳解

    這篇文章主要介紹了Java基礎(chǔ)開發(fā)之?dāng)?shù)據(jù)導(dǎo)出Excel文件格式實(shí)例詳解,需要的朋友可以參考下
    2020-02-02

最新評(píng)論

普洱| 蒙山县| 克拉玛依市| 离岛区| 沅陵县| 长乐市| 辰溪县| 城市| 礼泉县| 襄垣县| 青阳县| 上虞市| 安西县| 奉化市| 农安县| 德化县| 凯里市| 桃园县| 搜索| 壶关县| 长宁县| 红原县| 保康县| 仪征市| 东丽区| 女性| 平凉市| 鞍山市| 吴旗县| 宣武区| 永定县| 南皮县| 南雄市| 西乌| 长汀县| 九江市| 化德县| 凌云县| 张家川| 石棉县| 裕民县|