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

Springboot如何正確使用AOP問(wèn)題

 更新時(shí)間:2025年06月24日 16:13:50   作者:yololee_  
這篇文章主要介紹了Springboot如何正確使用AOP問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

?一、AOP概念

切面(Aspect)

  • 一個(gè)關(guān)注點(diǎn)的模塊化,這個(gè)關(guān)注點(diǎn)可能會(huì)橫切多個(gè)對(duì)象。
  • 事務(wù)管理是J2EE應(yīng)用中一個(gè)關(guān)于橫切關(guān)注點(diǎn)的很好的例子。
  • 在Spring AOP中,切面可以使用基于模式或者基于@Aspect注解的方式來(lái)實(shí)現(xiàn)

連接點(diǎn)(JoinPoint)

在程序執(zhí)行過(guò)程中某個(gè)特定的點(diǎn),比如某方法調(diào)用的時(shí)候或者處理異常的時(shí)候。在SpringAOP中,一個(gè)連接點(diǎn)總是表示一個(gè)方法的執(zhí)行

通知(Advice)

  • 在切面的某個(gè)特定的連接點(diǎn)上執(zhí)行的動(dòng)作。
  • 其中包括了Around、Before和After等不同類(lèi)型的通知。
  • 許多AOP框架(包括Spring)都是以攔截器做通知模型,并維護(hù)一個(gè)以連接點(diǎn)為中心的攔截器鏈

切入點(diǎn)(PointCut)

  • 匹配連接點(diǎn)的斷言。
  • 通知和一個(gè)切入點(diǎn)表達(dá)式關(guān)聯(lián),并在滿足這個(gè)切入點(diǎn)的連接點(diǎn)上運(yùn)行(例如,當(dāng)執(zhí)行某個(gè)特定名稱(chēng)的方法時(shí)),切入點(diǎn)表達(dá)式如何和連接點(diǎn)匹配是AOP的核心:Spring缺省使用AspectJ切入點(diǎn)語(yǔ)法

引入(Intorduction)

  • 用來(lái)給一個(gè)類(lèi)型聲明額外的方法或?qū)傩裕ㄒ脖环Q(chēng)為連接類(lèi)型聲明)。
  • Spring允許引入新的接口(以及一個(gè)對(duì)應(yīng)的實(shí)現(xiàn))到任何被代理的對(duì)象。
  • 例如,你可以使用引入來(lái)使一個(gè)bean實(shí)現(xiàn)接口,以便簡(jiǎn)化緩存機(jī)制

目標(biāo)對(duì)象(Target Object)

  • 被一個(gè)或者多個(gè)切面所通知的對(duì)象。也被稱(chēng)做被通知對(duì)象。
  • 既然Spring AOP是通過(guò)運(yùn)行時(shí)代理實(shí)現(xiàn)的,這個(gè)對(duì)象永遠(yuǎn)是一個(gè)被代理對(duì)象

AOP代理(Aop proxy)

  • AOP框架創(chuàng)建的對(duì)象,用來(lái)實(shí)現(xiàn)切面契約(例如通知方法執(zhí)行等等)。
  • 在Spring中,AOP代理可以是JDK動(dòng)態(tài)代理或者CGLIB代理

植入(weaving)

  • 把切面連接到其它的應(yīng)用程序類(lèi)型或者對(duì)象上,并創(chuàng)建一個(gè)被通知的對(duì)象。
  • 這些可以在編譯時(shí)(例如使用AspectJ編譯器),類(lèi)加載時(shí)和運(yùn)行時(shí)完成。
  • Spring和其他純Java AOP框架一樣,在運(yùn)行時(shí)完成織入

二、切點(diǎn)表達(dá)式?

execution表達(dá)式

用于匹配方法執(zhí)行的連接點(diǎn),屬于方法級(jí)別

語(yǔ)法:

execution(修飾符 返回值類(lèi)型 方法名(參數(shù))異常)

語(yǔ)法參數(shù)描述
修飾符可選,如public,protected,寫(xiě)在返回值前,任意修飾符填*號(hào)就可以
返回值類(lèi)型必選,可以使用*來(lái)代表任意返回值
方法名必選,可以用*來(lái)代表任意方法
參數(shù)()代表是沒(méi)有參數(shù),(..)代表是匹配任意數(shù)量,任意類(lèi)型的參數(shù),當(dāng)然也可以指定類(lèi)型的參數(shù)進(jìn)行匹配,如要接受一個(gè)String類(lèi)型的參數(shù),則(java.lang.String), 任意數(shù)量的String類(lèi)型參數(shù):(java.lang.String..)
異常可選,語(yǔ)法:throws 異常,異常是完整帶包名,可以是多個(gè),用逗號(hào)分隔

符號(hào):

符號(hào)描述
*匹配任意字符
匹配多個(gè)包或者多個(gè)參數(shù)
+表示類(lèi)及其子類(lèi)

條件符:

符號(hào)描述
&&、and
||
!

案例

攔截com.gj.web包下的所有子包里的任意類(lèi)的任意方法

execution(* com.gj.web..*.*(..))

攔截com.gj.web.api.Test2Controller下的任意方法

execution(* com.gj.web.api.Test2Controller.*(..))

攔截任何修飾符為public的方法

execution(public * * (..))

攔截com.gj.web下的所有子包里的以ok開(kāi)頭的方法

execution(* com.gj.web..*.ok*(..))

三、AOP通知

在切面類(lèi)中需要定義切面方法用于響應(yīng)響應(yīng)的目標(biāo)方法,切面方法即為通知方法,通知方法需要用注解標(biāo)識(shí),AspectJ支持5種類(lèi)型的通知注解

注解描述
@Before前置通知, 在方法執(zhí)行之前執(zhí)行
@After后置通知, 在方法執(zhí)行之后執(zhí)行
@AfterReturn返回通知, 在方法返回結(jié)果之后執(zhí)行
@AfterThrowing異常通知, 在方法拋出異常之后
@Around環(huán)繞通知,圍繞方法的執(zhí)行

@Before

    @Before("testCut()")
    public void cutProcess(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        System.out.println("注解方式AOP開(kāi)始攔截, 當(dāng)前攔截的方法名: " + method.getName());
    }

@After

    @After("testCut()")
    public void after(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        System.out.println("注解方式AOP執(zhí)行的方法 :"+method.getName()+" 執(zhí)行完了");
    }

@AfterReturn:其中value表示切點(diǎn)方法,returning表示返回的結(jié)果放到result這個(gè)變量中

    /**
     * returning屬性指定連接點(diǎn)方法返回的結(jié)果放置在result變量中
     * @param joinPoint 連接點(diǎn)
     * @param result 返回結(jié)果
     */
    @AfterReturning(value = "testCut()",returning = "result")
    public void afterReturn(JoinPoint joinPoint, Object result) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        System.out.println("注解方式AOP攔截的方法執(zhí)行成功, 進(jìn)入返回通知攔截, 方法名為: "+method.getName()+", 返回結(jié)果為: "+result.toString());
    }

@AfterThrowing:其中value表示切點(diǎn)方法,throwing表示異常放到e這個(gè)變量

    @AfterThrowing(value = "testCut()", throwing = "e")
    public void afterThrow(JoinPoint joinPoint, Exception e) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        System.out.println("注解方式AOP進(jìn)入方法異常攔截, 方法名為: " + method.getName() + ", 異常信息為: " + e.getMessage());
    }

@Around

    @Around("testCut()")
    public Object testCutAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("注解方式AOP攔截開(kāi)始進(jìn)入環(huán)繞通知.......");
            Object proceed = joinPoint.proceed();
            System.out.println("準(zhǔn)備退出環(huán)繞......");
            return proceed;
    }

四、springboot中使用AOP

導(dǎo)出依賴(lài)

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

在這里插入圖片描述

自定義注解

package com.hl.springbootrunner.aop;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AOPAnnotations {
}

創(chuàng)建切面類(lèi)

package com.hl.springbootrunner.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;


@Aspect
@Component
public class TestAspect {

    /**
     * 這里的路徑填自定義注解的全路徑
     */
    @Pointcut("@annotation(com.hl.springbootrunner.aop.AOPAnnotations)")
    public void testCut() {

    }

    @Before("testCut()")
    public void cutProcess(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        System.out.println("注解方式AOP開(kāi)始攔截, 當(dāng)前攔截的方法名: " + method.getName());
    }

    @After("testCut()")
    public void after(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        System.out.println("注解方式AOP執(zhí)行的方法 :" + method.getName() + " 執(zhí)行完了");
    }


    @Around("testCut()")
    public Object testCutAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("注解方式AOP攔截開(kāi)始進(jìn)入環(huán)繞通知.......");
        Object proceed = joinPoint.proceed();
        System.out.println("準(zhǔn)備退出環(huán)繞......");
        return proceed;
    }

    /**
     * returning屬性指定連接點(diǎn)方法返回的結(jié)果放置在result變量中
     *
     * @param joinPoint 連接點(diǎn)
     * @param result    返回結(jié)果
     */
    @AfterReturning(value = "testCut()", returning = "result")
    public void afterReturn(JoinPoint joinPoint, Object result) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        System.out.println("注解方式AOP攔截的方法執(zhí)行成功, 進(jìn)入返回通知攔截, 方法名為: " + method.getName() + ", 返回結(jié)果為: " + result.toString());
    }

    @AfterThrowing(value = "testCut()", throwing = "e")
    public void afterThrow(JoinPoint joinPoint, Exception e) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        System.out.println("注解方式AOP進(jìn)入方法異常攔截, 方法名為: " + method.getName() + ", 異常信息為: " + e.getMessage());
    }

}

自定義一個(gè)接口

@RestController
public class TestController {
 
    @GetMapping("/ok")
    @AOPAnnotations
    public String test2() {
        return "ok";
    }
 
}

測(cè)試

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java實(shí)現(xiàn)角色及菜單權(quán)限的項(xiàng)目實(shí)踐

    java實(shí)現(xiàn)角色及菜單權(quán)限的項(xiàng)目實(shí)踐

    在Java中,實(shí)現(xiàn)角色及菜單權(quán)限管理涉及定義實(shí)體類(lèi)、設(shè)計(jì)數(shù)據(jù)庫(kù)表、實(shí)現(xiàn)服務(wù)層和控制器層,這種管理方式有助于有效控制用戶權(quán)限,適用于企業(yè)級(jí)應(yīng)用,感興趣的可以一起來(lái)了解一下
    2024-09-09
  • Java實(shí)現(xiàn)二叉堆、大頂堆和小頂堆

    Java實(shí)現(xiàn)二叉堆、大頂堆和小頂堆

    二叉堆就是完全二叉樹(shù),或者是靠近完全二叉樹(shù)結(jié)構(gòu)的二叉樹(shù)。大頂堆要求對(duì)于一個(gè)節(jié)點(diǎn)來(lái)說(shuō),它的左右節(jié)點(diǎn)都比它小;小頂堆要求對(duì)于一個(gè)節(jié)點(diǎn)來(lái)說(shuō),它的左右節(jié)點(diǎn)都比它大。本文將用Java分別實(shí)現(xiàn)二叉堆、大頂堆和小頂堆。需要的可以參考一下
    2022-01-01
  • IntelliJ IDEA使用git初始化倉(cāng)庫(kù)的使用方法

    IntelliJ IDEA使用git初始化倉(cāng)庫(kù)的使用方法

    這篇文章主要介紹了IntelliJ IDEA使用git初始化倉(cāng)庫(kù)的使用方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Spring @Bean注解的使用場(chǎng)景與案例實(shí)現(xiàn)

    Spring @Bean注解的使用場(chǎng)景與案例實(shí)現(xiàn)

    隨著SpringBoot的流行,我們現(xiàn)在更多采用基于注解式的配置從而替換掉了基于XML的配置,所以本篇文章我們主要探討基于注解的@Bean以及和其他注解的使用
    2023-03-03
  • Springboot maven plugin插件原理及作用

    Springboot maven plugin插件原理及作用

    這篇文章主要介紹了Springboot maven plugin插件原理及作用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • 利用Jackson解析JSON的詳細(xì)實(shí)現(xiàn)教程

    利用Jackson解析JSON的詳細(xì)實(shí)現(xiàn)教程

    JSON對(duì)于開(kāi)發(fā)者并不陌生,如今的WEB服務(wù)等都是以JSON作為數(shù)據(jù)交換的格式。學(xué)習(xí)JSON格式的操作工具對(duì)開(kāi)發(fā)者來(lái)說(shuō)是必不可少的。本文將介紹如何使用Jackson開(kāi)源工具庫(kù)對(duì)JSON進(jìn)行常見(jiàn)操作,需要的可以參考一下
    2022-07-07
  • Java實(shí)現(xiàn)定時(shí)器的4種方法超全總結(jié)

    Java實(shí)現(xiàn)定時(shí)器的4種方法超全總結(jié)

    對(duì)于一些特殊的代碼是需要定時(shí)執(zhí)行的,下面來(lái)看看定時(shí)器該如何編寫(xiě)吧,下面這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)定時(shí)器的4種方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • Java GZIP壓縮與解壓縮代碼實(shí)例

    Java GZIP壓縮與解壓縮代碼實(shí)例

    這篇文章主要介紹了Java GZIP壓縮與解壓縮代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • 基于Java實(shí)現(xiàn)Socket編程入門(mén)

    基于Java實(shí)現(xiàn)Socket編程入門(mén)

    Java最初是作為網(wǎng)絡(luò)編程語(yǔ)言出現(xiàn)的,使得客戶端和服務(wù)器的溝通變成了現(xiàn)實(shí),而在網(wǎng)絡(luò)編程中,使用最多的就是Socket,本文就來(lái)介紹一下基于Java實(shí)現(xiàn)Socket編程入門(mén),感興趣的可以來(lái)了解一下
    2022-03-03
  • Spring init-method與destroy-method屬性的用法解析

    Spring init-method與destroy-method屬性的用法解析

    這篇文章主要介紹了Spring init-method與destroy-method屬性的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評(píng)論

二连浩特市| 淅川县| 麟游县| 文成县| 岱山县| 桦川县| 大邑县| 体育| 许昌县| 隆化县| 泾源县| 宁阳县| 河津市| 政和县| 边坝县| 商南县| 富裕县| 竹溪县| 梧州市| 宁南县| 砚山县| 旬阳县| 白银市| 永济市| 白河县| 武宣县| 黄梅县| 乐业县| 江山市| 凤台县| 东乡族自治县| 托克托县| 新河县| 巩留县| 遂溪县| 铜山县| 宁陕县| 大连市| 凤山县| 湟源县| 法库县|