亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

SpringBoot基礎(chǔ)篇AOP之基本使用姿勢小結(jié)

timger / 3379人閱讀

摘要:通知和切點共同定義了關(guān)于切面的全部內(nèi)容,它是什么時候,在何時和何處完成功能引入允許我們向現(xiàn)有的類添加新的方法或者屬性組裝方面來創(chuàng)建一個被通知對象。這可以在編譯時完成例如使用編譯器,也可以在運行時完成。和其他純框架一樣,在運行時完成織入。

原文:190301-SpringBoot基礎(chǔ)篇AOP之基本使用姿勢小結(jié)

一般來講,談到Spring的特性,繞不過去的就是DI(依賴注入)和AOP(切面),在將bean的系列中,說了DI的多種使用姿勢;接下來看一下AOP的玩法

I. 背景知識

在實際使用之前有必要了解一下什么是AOP,以及AOP的幾個基本概念

1. advice

before: 在方法執(zhí)行之前被調(diào)用

after: 在方法執(zhí)行之后調(diào)用

after returning: 方法執(zhí)行成功之后

after throwing: 方法拋出異常之后

around: 環(huán)繞,自己在內(nèi)部決定方法的執(zhí)行時機(jī),因此可以在之前之后做一些業(yè)務(wù)邏輯

2. join point

連接點,比如方法調(diào)用,方法執(zhí)行,字段設(shè)置/獲取、異常處理執(zhí)行、類初始化、甚至是 for 循環(huán)中的某個點

但 Spring AOP 目前僅支持方法執(zhí)行 (method execution)

簡單來說,Spring AOP中,PointCut就是那個被攔截的方法

3. pointcut

切點,用來描述滿足什么規(guī)則的方法會被攔截

正則表達(dá)式 : @Before("execution(public * com.git.hui.demo.base.bean.*.*(..))")

注解攔截方式 :@Around("@annotation(parameterCheck)")

4. aspect

切面是切點和通知的結(jié)合。通知和切點共同定義了關(guān)于切面的全部內(nèi)容,它是什么時候,在何時和何處完成功能

5. introduction

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

6. weaving

組裝方面來創(chuàng)建一個被通知對象。這可以在編譯時完成(例如使用AspectJ編譯器),也可以在運行時完成。Spring和其他純Java AOP框架一樣,在運行時完成織入。

簡單來講就是生成一個代理類,在調(diào)用被攔截的方法時,實際上執(zhí)行的是代理類,這個代理類內(nèi)部執(zhí)行切面邏輯

II. 使用說明 1. 基本配置

首先是基本環(huán)境的搭建, 先貼上必要的xml配置, 使用aop需要引入包: spring-boot-starter-aop


    org.springframework.boot
    spring-boot-starter-parent
    2.0.4.RELEASE
     



    UTF-8
    UTF-8
    Finchley.RELEASE
    1.8




    
        org.springframework.boot
        spring-boot-starter-aop
    



    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    



    
        spring-milestones
        Spring Milestones
        https://repo.spring.io/milestone
        
            false
        
    
2. 代碼準(zhǔn)備

首先創(chuàng)建一個被攔截的bean: com.git.hui.boot.aop.demo.DemoBean,如下

@Component
public class DemoBean {

    /**
     * 返回隨機(jī)的字符串
     *
     * @param time
     * @return
     */
    public String randUUID(long time) {
        try {
            System.out.println("in randUUID before process!");
            return UUID.randomUUID() + "|" + time;
        } finally {
            System.out.println("in randUUID finally!");
        }
    }
}

接著在啟動類中,執(zhí)行

@SpringBootApplication
public class Application {
    
    public Application(DemoBean demoBean) {
        String ans = demoBean.randUUID(System.currentTimeMillis());
        System.out.println("----- ans: " + ans + "---------");
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}
3. AOP使用

在實際使用之前,需要創(chuàng)建一個切面,用@Aspect聲明,其次切面也需要作為bean托付給Spring容器管理

@Aspect
@Component
public class AnoAspcet {
}
a. before

在方法調(diào)用之前,需要執(zhí)行一些操作,這個時候可以使用 @Before 注解來聲明before advice

一種可使用姿勢如下,我們的切點直接在注解中進(jìn)行定義,使用正則表達(dá)式的方式

@Before("execution(public * com.git.hui.boot.aop.demo.*.*(*))")
public void doBefore(JoinPoint joinPoint) {
    System.out.println("do in Aspect before method called! args: " + JSON.toJSONString(joinPoint.getArgs()));
}
b. after

在方法調(diào)用完畢之后,再執(zhí)行一些操作,這個時候after就可以派上用場,為了考慮切點的通用性,我們可以考慮聲明一個切點,使用@Pointcut注解

@Pointcut("execution(public * com.git.hui.boot.aop.demo.*.*(*))")
public void point() {
}

使用pointcut的方式也比較簡單,如下

@After("point()")
public void doAfter(JoinPoint joinPoint) {
    System.out.println("do in Aspect after method called! args: " + JSON.toJSONString(joinPoint.getArgs()));
}
c. after returning

在正常返回結(jié)果之后,再次執(zhí)行,這個也挺有意思的,通常使用這個advice時,一般希望獲取返回結(jié)果,那么應(yīng)該怎么處理呢?

org.aspectj.lang.annotation.AfterReturning#returning 指定返回結(jié)果對應(yīng)參數(shù)name

返回結(jié)果作為參數(shù)傳入,要求類型一致,否則不生效

/**
 * 執(zhí)行完畢之后,通過 args指定參數(shù);通過 returning 指定返回的結(jié)果,要求返回值類型匹配
 *
 * @param time
 * @param result
 */
@AfterReturning(value = "point() && args(time)", returning = "result")
public void doAfterReturning(long time, String result) {
    System.out.println("do in Aspect after method return! args: " + time + " ans: " + result);
}
d. around

這個也比較常見,在方法執(zhí)行前后干一些事情,比如常見的耗時統(tǒng)計,日志打印,安全控制等,很多都是基于around advice實現(xiàn)的

使用這個advice需要注意的是傳入?yún)?shù)類型為 ProceedingJoinPoint,需要在方法內(nèi)部顯示執(zhí)行org.aspectj.lang.ProceedingJoinPoint#proceed()來表示調(diào)用方法

@Around("point()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
    System.out.println("do in Aspect around ------ before");
    Object ans = joinPoint.proceed();
    System.out.println("do in Aspect around ------- over! ans: " + ans);
    return ans;
}
e. 輸出

執(zhí)行之后輸出如下

do in Aspect around ------ before
do in Aspect before method called! args: [1551433188205]
in randUUID before process!
in randUUID finally!
do in Aspect around ------- over! ans: 6849544b-160e-464c-80bd-641f2651c6c1|1551433188205
do in Aspect after method called! args: [1551433188205]
do in Aspect after method return! args: 1551433188205 ans: 6849544b-160e-464c-80bd-641f2651c6c1|1551433188205
----- ans: 6849544b-160e-464c-80bd-641f2651c6c1|1551433188205---------

從輸出結(jié)果上,可以看到每個advice的使用范圍,當(dāng)然也帶來了一些疑問

可以存在多個同類型的advice,攔截同一個目標(biāo)嗎?(如兩個around都攔截methodA方法,那么methodA方法被調(diào)用時,兩個around advice是否都會執(zhí)行)

多個advice之間的優(yōu)先級怎么定義?

aop攔截的目標(biāo)方法有沒有限制(對非public的方法可以攔截么?)

被攔截的方法中存在相互調(diào)用的時候,會怎樣?(如methodA,methodB都可以被攔截,且methodA中調(diào)用了methodB,那么在執(zhí)行methodA時,methodB的各種advice是否會被觸發(fā)?)

基于注解的aop方式可以怎樣用

以上這些問題留在下一篇進(jìn)行介紹

III. 其他 0. 項目

工程:https://github.com/liuyueyi/spring-boot-demo

項目: https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-boot/010-aop

1. 一灰灰Blog

一灰灰Blog個人博客 https://blog.hhui.top

一灰灰Blog-Spring專題博客 http://spring.hhui.top

一灰灰的個人博客,記錄所有學(xué)習(xí)和工作中的博文,歡迎大家前去逛逛

2. 聲明

盡信書則不如,以上內(nèi)容,純屬一家之言,因個人能力有限,難免有疏漏和錯誤之處,如發(fā)現(xiàn)bug或者有更好的建議,歡迎批評指正,不吝感激

微博地址: 小灰灰Blog

QQ: 一灰灰/3302797840

3. 掃描關(guān)注

一灰灰blog

知識星球

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

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/19468.html

相關(guān)文章

  • 慕課網(wǎng)_《SpringBoot進(jìn)階Web進(jìn)階》學(xué)習(xí)總結(jié)

    摘要:時間年月日星期日說明本文部分內(nèi)容均來自慕課網(wǎng)。慕課網(wǎng)教學(xué)示例源碼個人學(xué)習(xí)源碼第一章課程介紹課程介紹本課程緊接著小時學(xué)會課程,請先看入門課。異常返回通知在連接點拋出異常后執(zhí)行。 時間:2017年3月19日星期日說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)示例源碼:https://github.com/zccodere/s...個人學(xué)習(xí)源碼:htt...

    lifefriend_007 評論0 收藏0
  • SpringBoot高級MongoDB修改基本使用姿勢

    摘要:原文高級篇之修改基本使用姿勢本篇依然是中的一篇,主要介紹的更新,主要內(nèi)容如下常見類型成員的修改數(shù)組類型成員的增刪改類型成員的增刪改基本使用首先是準(zhǔn)備好基本環(huán)境,可以參考博文高級篇之基本環(huán)境搭建與使用高級篇之查詢基本使用姿勢在開 原文: 190218-SpringBoot高級篇MongoDB之修改基本使用姿勢 本篇依然是MongoDB curd中的一篇,主要介紹document的更新,...

    lauren_liuling 評論0 收藏0
  • 【好好面試】學(xué)完Aop,連動態(tài)代理的原理都不懂?

    摘要:總結(jié)動態(tài)代理的相關(guān)原理已經(jīng)講解完畢,接下來讓我們回答以下幾個思考題。 【干貨點】 此處是【好好面試】系列文的第12篇文章。文章目標(biāo)主要是通過原理剖析的方式解答Aop動態(tài)代理的面試熱點問題,通過一步步提出問題和了解原理的方式,我們可以記得更深更牢,進(jìn)而解決被面試官卡住喉嚨的情況。問題如下 SpringBoot默認(rèn)代理類型是什么 為什么不用靜態(tài)代理 JDK動態(tài)代理原理 CGLIB動態(tài)代理...

    Keven 評論0 收藏0

發(fā)表評論

0條評論

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