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

Springboot AOP開發(fā)教程

 更新時間:2024年03月02日 09:53:17   作者:我不配擁有55kg的你  
AOP是OOP的延續(xù),是軟件開發(fā)中的一個熱點,也是Spring框架中的一個重要內(nèi)容,是函數(shù)式編程的一種衍生范型,本文給大家介紹Springboot AOP開發(fā)教程,感興趣的朋友跟隨小編一起看看吧

Springboot AOP開發(fā)

簡介

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

一 AOP概述

AOP,即面向切面編程,簡言之,面向方法編程。

針對方法,在方法的執(zhí)行前或執(zhí)行后使用,用于增強方法,或拓展。

二 AOP開發(fā)

1.引入 spring-boot-starter-aop

在SpringBoot項目的pom文件中,引入 spring-boot-starter-aop依賴。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2.示例:計算方法執(zhí)行時間

1.創(chuàng)建實體類,通過注解來申明該類的類型,并將該類交給Spring的IOC容器來管理。

通過注解 @Aspect 申明這是一個AOP類

通過 @Component 將其交給IOC容器管理

@Aspect
@Component
public class TimeAspect {
    //code
}

2.創(chuàng)建方法并且實現(xiàn)

@Aspect
@Component
@Slf4j
public class TimeAspect {
    // 針對 com.shawn.springboot03.service 包下所有的方法進行編程,
    // * com.shawn.springboot03.service.*.*(..)) 為切入點表達式
    @Around("execution(* com.shawn.springboot03.service.*.*(..))")
    public Object recordTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long startTime=System.currentTimeMillis();
        // 切面對象,執(zhí)行具體的業(yè)務(wù)方法
        Object object = proceedingJoinPoint.proceed();
        long endTime=System.currentTimeMillis();
        log.info("方法耗時為{}ms",endTime-startTime);
        return object;
    }
}

通過以上方法,當(dāng)用戶調(diào)用 service 層接口的任一方法時都會計算方法的運行時間。

3.AOP編程的優(yōu)點:

  • 代碼無侵入:無需修改原始方法
  • 減少代碼重復(fù),提高開發(fā)效率:只需編寫一次
  • 維護方便:根據(jù)業(yè)務(wù)需求,調(diào)整切入點表達式即可

三 AOP詳解

1.AOP核心概念

1.連接點(JoinPoint):連接點指的是可以被AOP控制的方法,以及方法執(zhí)行時的相關(guān)信息。

2.通知(Advice):Advice指的是被抽取出來的共性功能,即重復(fù)的那部分邏輯。

3.切入點(PointCut):匹配連接點的條件,通知僅會在切入點方法執(zhí)行時被應(yīng)用

4.切面(Aspcet):描述通知與切入點的關(guān)系

5.目標(biāo)對象(Target):通知所應(yīng)用的對象

2.AOP通知類型

  • @Around:環(huán)繞通知,此注解標(biāo)注的方法在目標(biāo)方法前后都會執(zhí)行
  • @Before:前置通知,此注解標(biāo)注的方法僅在方法執(zhí)行前被執(zhí)行
  • @After:后置通知,此注解在方法執(zhí)行完成后執(zhí)行,不論是否拋出異常
  • @AfterReturning:返回后通知,此注解標(biāo)注的方法在目標(biāo)方法后被執(zhí)行,有異常不通知
  • @AfterThrowing:異常后通知,此注解的通知方法發(fā)生異常后執(zhí)行

3.各通知類型演示

創(chuàng)建一個 TestAspect 類,用于演示各種通知類型

@Around 通知類型

介紹:在方法前后均執(zhí)行

切入點表達式格式: 返回值 包名.方法名(形參)

其中 * 代表全部,.. 代表任意多的參數(shù)

切入點表達式示例說明:

* com.shawn.test.server.*(..) 表示 任意返回值的 com.shawn.test.server包下任意返回值,任意多參數(shù)的全部方法。

@Aspect
@Component
@Slf4j
public class TestAspect {
    @Around("execution(* com.shawn.springboot03.service.impl.DeptServiceImpl.*(..))")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //方法執(zhí)行前的業(yè)務(wù)邏輯
        //code..
        //執(zhí)行原始方法(即連接點),并且接收原始方法的返回值
        Object proceed = proceedingJoinPoint.proceed();
        //方法執(zhí)行后的業(yè)務(wù)邏輯
        //code..
        //返回原始方法的返回值
        return proceed;
    }
}

ProceedingJoinPoint是一個接口類,指代程序執(zhí)行過程中的一個特定點,其中包含了原始方法的全部內(nèi)容,包括方法名,參數(shù)值等。

在使用 @Around通知類型時,需要將該對象作為參數(shù)傳遞進來,用于后續(xù)執(zhí)行原始方法或獲取原始方法的其他信息。

ProceedingJoinPoint僅能作用于 @Around 類型的通知上。

2.@Before 通知類型

介紹:此注解標(biāo)注的方法僅在原始方法執(zhí)行前執(zhí)行

@Aspect
@Component
@Slf4j
public class TestAspect {
    @Before("execution(* com.shawn.springboot03.service.*.*(..))")
    public void before(){
        // 方法執(zhí)行前的業(yè)務(wù)邏輯
        //code..
    }
}

3.@After 通知類型

介紹:此注解標(biāo)注的方法,僅在原始方法執(zhí)行后執(zhí)行,且不論原始方法是否執(zhí)行,該通知都會執(zhí)行

@Aspect
@Component
@Slf4j
public class TestAspect {
    @After("execution(* com.shawn.springboot03.service.*.*(..))")
    public void after(){
        // 方法執(zhí)行后的業(yè)務(wù)邏輯
        //code..
    }
}

4.@AfterReturning 通知類型

介紹:此注解標(biāo)注的方法,僅在原始方法執(zhí)行完成后通知,即當(dāng)原始方法執(zhí)行發(fā)生異常時,@AfterReturning 通知不會被執(zhí)行。

@Aspect
@Component
@Slf4j
public class TestAspect {
    @AfterReturning("execution(* com.shawn.springboot03.service.*.*(..))")
    public void afterReturning(){
        //方法執(zhí)行完成的業(yè)務(wù)邏輯
        //code..
    }
}

5.@AfterThrowing通知類型

介紹:次注解標(biāo)注的方法,僅在原始方法執(zhí)行過程中發(fā)生了異常,才會執(zhí)行。

@Aspect
@Component
@Slf4j
public class TestAspect {
    /**
     * 聲明一個空的方法體來定義切入點表達式
     * 使用 @Pointcut 注解來定義切入點表達式
     */
    @Pointcut("execution(* com.shawn.springboot03.service.impl.DeptServiceImpl.*(..))")
    private void point(){};
    @After("point()")
    public void after(){
        // 方法執(zhí)行后的業(yè)務(wù)邏輯
        //code..
    }
}

4.定義切入點

以上示例中的切入點表達式均相似,可以利用封裝的思想,將切入點表達式全部抽取出來,在需要的時候直接使用即可。

想要實現(xiàn)以上需求,則需要自定義切入點表達式

通過 @Pointcut 注解,來定義切入點表達式,然后在需要編寫切入點表達式的地方調(diào)用即可。

@Aspect
@Component
public class TestAspect {
    @Pointcut("@annotation(com.shawn.springboot03.annotation.OperationLog)")
    private void point(){};
    @AfterThrowing("point()")
    public void afterThrowing(){
        //方法執(zhí)行時拋出異常的業(yè)務(wù)邏輯
        //code..
    }
}

注意:如果自定義的切入點訪問修飾符為 public ,則該表達式還可以在其他切面類中被引用。具體使用可根據(jù)實際業(yè)務(wù)情況決定。

定義切入點總共有兩種辦法,一種是通過方法名來定義切入點,還可以通過注解來定義切入點。

示例:以下示例使用自定義注解作為切入點,使用了以下自定義注解的方法會執(zhí)行通知。

@Aspect
@Component
@Slf4j
@Order(3)
public class TestAspect {
    @Pointcut("execution(* com.shawn.springboot03.service.impl.DeptServiceImpl.*(..))")
    private void point(){};
    @After("point()")
    public void after(){
        // 方法執(zhí)行后的業(yè)務(wù)邏輯
        //code..
    }
}

5.通知順序

當(dāng)有多個切入點都匹配到了目標(biāo)方法,目標(biāo)方法運行時,多個通知都會被執(zhí)行。

某些情況下則需要控制通知的順序,可以在切面類上使用 @Order 注解來控制順序

@Aspect
@Component
@Slf4j
@Order(3)
public class TestAspect {
    @Pointcut("execution(* com.shawn.springboot03.service.impl.DeptServiceImpl.*(..))")
    private void point(){};
    @After("point()")
    public void after(){
        // 方法執(zhí)行后的業(yè)務(wù)邏輯
        //code..
    }
}

注意:@Order(number) 注解中,數(shù)字越小的越先運行,越大的越后運行。

默認(rèn)情況下,按照切面類的類名排序順序執(zhí)行。

四 切入點表達式

1.execution

execution 主要根據(jù)方法的返回值,包名類名,方法名,方法參數(shù)等信息來匹配,語法為:

execution( 訪問修飾符? 返回值 包名.類名.?方法名(方法參數(shù)) throw 異常? )

其中帶 ? 的表示可以省略的部分

  • 訪問修飾符:可省略(比如:public,protected)
  • 包名.類名:可省略
  • throws 異常:可省略(注意是方法上聲明拋出的異常,不是實際拋出的異常)

以下是一個完整示例:

@Before ("execution(public void com.itheima.service.impl.DeptserviceImpl.delete (java.lang.Integer)) throws Exception")
private void point(){};

省略后的示例:

@Before ("execution(void delete (java.lang.Integer))")
private void point(){};

此時,所有 void delete (java.lang.Integer) 方法都將被匹配到。

注意: * 用于描述匹配單個, … 可以用來匹配多個連續(xù),?表示可省略

在這里插入圖片描述

2.@annotation

@annotation 切入點表達式,用于匹配標(biāo)識有特定注解的方法。

示例:

@Pointcut("@annotation(com.shawn.annotation.OperationLog)")
private void point(){};

五 連接點

在Spring中使用JoinPoint抽象了連接點,使用它可以獲取方法執(zhí)行時的相關(guān)信息,入目標(biāo)類名,方法名,方法參數(shù)等。

1.對于 @Around 通知,獲取連接點信息只能使用 ProceedingJoinPoint

@Around("point()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    //獲取目標(biāo)類名
    String name = proceedingJoinPoint.getTarget().getClass().getName();
    log.info("獲取目標(biāo)類名:"+name);
    //獲取方法執(zhí)行參數(shù)
    Object[] args = proceedingJoinPoint.getArgs();
    log.info("獲取方法執(zhí)行參數(shù):"+JSON.toJSONString(args));
    //獲取目標(biāo)方法名
    String methodName = proceedingJoinPoint.getSignature().getName();
    log.info("獲取目標(biāo)方法名:"+methodName);
    //執(zhí)行原始方法(即連接點),并且接收原始方法的返回值
    Object proceed = proceedingJoinPoint.proceed();
    //獲取方法的返回值
    log.info("獲取方法的返回值:"+JSON.toJSONString(proceed));
    //返回原始方法的返回值
    return proceed;
}

proceedingJoinPoint.proceed()得到目標(biāo)方法的結(jié)果再返回,此處可以對目標(biāo)方法執(zhí)行的結(jié)果進行篡改。

2.對于其他四種通知,獲取連接點信息只能使用 JoinPoint , 它是 ProceedingJoinPoint 的父類。

@Before("point()")
public void before(JoinPoint joinPoint){
    // 獲取目標(biāo)方法的類名
    String name = joinPoint.getTarget().getClass().getName();
    log.info("獲取目標(biāo)方法的類名:"+name);
    String methodName = joinPoint.getSignature().getName();
    log.info("獲取目標(biāo)方法的方法名:"+methodName);
    //獲取目標(biāo)方法的運行參數(shù)
    Object[] args = joinPoint.getArgs();
    log.info("獲取目標(biāo)方法的參數(shù):"+JSON.toJSONString(args));
}

3.除@Around 通知外,還可以獲取到方法執(zhí)行結(jié)果的通知類型為 @AfterReturning,@AfterReturning 在方法執(zhí)行完成并且無異常時通知。

在定義@AfterReturning通知類型時,使用 pointcut 屬性定義切入點,returning屬性定義返回值對象,然后在方法參數(shù)中傳入即可。

@AfterReturning(pointcut = "point()",returning = "object")
public void afterReturning(JoinPoint joinPoint, Object object){
    // 獲取目標(biāo)方法的類名
    String name = joinPoint.getTarget().getClass().getName();
    log.info("獲取目標(biāo)方法的類名:"+name);
    String methodName = joinPoint.getSignature().getName();
    log.info("獲取目標(biāo)方法的方法名:"+methodName);
    //獲取目標(biāo)方法的運行參數(shù)
    Object[] args = joinPoint.getArgs();
    log.info("獲取目標(biāo)方法的參數(shù):"+JSON.toJSONString(args));
    //獲取方法返回值
    log.info("獲取方法返回值:"+JSON.toJSONString(object));
}

到此這篇關(guān)于Springboot AOP開發(fā)的文章就介紹到這了,更多相關(guān)Springboot AOP開發(fā)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java分層開發(fā)必知之PO、BO、DTO、VO、POJO概念實例詳解

    Java分層開發(fā)必知之PO、BO、DTO、VO、POJO概念實例詳解

    Java編程模型是一種在軟件開發(fā)中幫助組織和管理代碼的框架,其中,VO,BO,PO,DO,以及DTO是一些關(guān)鍵概念,它們在不同層次和階段起到重要作用,這篇文章主要介紹了Java分層開發(fā)必知之PO、BO、DTO、VO、POJO概念的相關(guān)資料,需要的朋友可以參考下
    2026-02-02
  • SpringBoot2 整合MinIO中間件實現(xiàn)文件便捷管理功能

    SpringBoot2 整合MinIO中間件實現(xiàn)文件便捷管理功能

    這篇文章主要介紹了SpringBoot2 整合MinIO中間件,實現(xiàn)文件便捷管理,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • java背包問題動態(tài)規(guī)劃算法分析

    java背包問題動態(tài)規(guī)劃算法分析

    這篇文章主要介紹了java背包問題動態(tài)規(guī)劃算法分析,想了解算法的同學(xué)一定要看一下
    2021-04-04
  • SpringBoot集成SAP的過程及本地IDEA啟動和Windows服務(wù)器部署

    SpringBoot集成SAP的過程及本地IDEA啟動和Windows服務(wù)器部署

    本文給大家介紹SpringBoot集成SAP的過程及本地IDEA啟動和Windows服務(wù)器部署的相關(guān)知識,本文給大家介紹的詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2025-07-07
  • 調(diào)用Process.waitfor導(dǎo)致的進程掛起問題及解決

    調(diào)用Process.waitfor導(dǎo)致的進程掛起問題及解決

    這篇文章主要介紹了調(diào)用Process.waitfor導(dǎo)致的進程掛起問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Sentinel熱門詞匯限流的實現(xiàn)詳解

    Sentinel熱門詞匯限流的實現(xiàn)詳解

    這篇文章主要介紹了使用Sentinel對熱門詞匯進行限流的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • 淺談Java由于不當(dāng)?shù)膱?zhí)行順序?qū)е碌乃梨i

    淺談Java由于不當(dāng)?shù)膱?zhí)行順序?qū)е碌乃梨i

    為了保證線程的安全,我們引入了加鎖機制,但是如果不加限制的使用加鎖,就有可能會導(dǎo)致順序死鎖(Lock-Ordering Deadlock)。本文將會討論一下順序死鎖的問題。
    2021-06-06
  • java代碼實現(xiàn)截圖功能(屏幕截圖)

    java代碼實現(xiàn)截圖功能(屏幕截圖)

    java代碼實現(xiàn)截圖功能,該JavaBean可以直接在其他Java應(yīng)用程序中調(diào)用,默認(rèn)的文件前綴為GuiCamera,文件格式為PNG格式,直接使用下面的類吧
    2013-12-12
  • Java接口RandomAccess全面了解

    Java接口RandomAccess全面了解

    下面小編就為大家?guī)硪黄狫ava接口RandomAccess全面了解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • 淺析mybatis和spring整合的實現(xiàn)過程

    淺析mybatis和spring整合的實現(xiàn)過程

    據(jù)官方的說法,在Mybatis3問世之前,Spring3的開發(fā)工作就已經(jīng)完成了,所以Spring3中還是沒有對Mybatis3的支持。因此由Mybatis社區(qū)自己開發(fā)了一個Mybatis-Spring用來滿足Mybatis用戶整合Spring的需求,下面通過Mybatis-Spring來整合Mybatis跟Spring的用法做介紹
    2015-10-10

最新評論

虞城县| 平昌县| 桓台县| 东丰县| 鸡西市| 连云港市| 景德镇市| 黑水县| 营山县| 界首市| 深州市| 玛多县| 岗巴县| 武安市| 九寨沟县| 沐川县| 江西省| 平定县| 巴中市| 东乡县| 文水县| 湘阴县| 左云县| 峨眉山市| 彭州市| 行唐县| 西华县| 东光县| 普安县| 宿迁市| 仁寿县| 怀来县| 光山县| 水富县| 辽阳市| 阳谷县| 勐海县| 达日县| 大城县| 沽源县| 休宁县|