欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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等不同類型的通知。
  • 許多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è)特定名稱的方法時(shí)),切入點(diǎn)表達(dá)式如何和連接點(diǎn)匹配是AOP的核心:Spring缺省使用AspectJ切入點(diǎn)語(yǔ)法

引入(Intorduction)

  • 用來(lái)給一個(gè)類型聲明額外的方法或?qū)傩裕ㄒ脖环Q為連接類型聲明)。
  • 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ì)象。也被稱做被通知對(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)用程序類型或者對(duì)象上,并創(chuàng)建一個(gè)被通知的對(duì)象。
  • 這些可以在編譯時(shí)(例如使用AspectJ編譯器),類加載時(shí)和運(yùn)行時(shí)完成。
  • Spring和其他純Java AOP框架一樣,在運(yùn)行時(shí)完成織入

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

execution表達(dá)式

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

語(yǔ)法:

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

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

符號(hào):

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

條件符:

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

案例

攔截com.gj.web包下的所有子包里的任意類的任意方法

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通知

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

注解描述
@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)出依賴

        <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)建切面類

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)文章

  • 新版SpringBoot無(wú)法主動(dòng)讀取bootstrap.yml的原因和解決方法

    新版SpringBoot無(wú)法主動(dòng)讀取bootstrap.yml的原因和解決方法

    在使用新版 Springboot 搭建微服務(wù)時(shí) 發(fā)現(xiàn)配置數(shù)據(jù)源失敗,依賴、配置、注解等所示所有均為正確,所以本文給大家介紹了新版SpringBoot無(wú)法主動(dòng)讀取bootstrap.yml的原因和解決方案,需要的朋友可以參考下
    2025-01-01
  • SpringBoot添加License的多種方式

    SpringBoot添加License的多種方式

    License指的是版權(quán)許可證,當(dāng)我們開(kāi)發(fā)完系統(tǒng)后,如果不想讓用戶一直白嫖使用,比如說(shuō)按時(shí)間續(xù)費(fèi),License的作用就有了。我們可以給系統(tǒng)指定License的有效期,控制系統(tǒng)的可用時(shí)間。
    2021-06-06
  • SpringBoot使用Spring-Data-Jpa實(shí)現(xiàn)CRUD操作

    SpringBoot使用Spring-Data-Jpa實(shí)現(xiàn)CRUD操作

    這篇文章主要為大家詳細(xì)介紹了SpringBoot使用Spring-Data-Jpa實(shí)現(xiàn)CRUD操作,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • Springcloud Config支持本地配置文件的方法示例

    Springcloud Config支持本地配置文件的方法示例

    這篇文章主要介紹了Springcloud Config支持本地配置文件的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • Java 程序里transient關(guān)鍵字使用方法示例

    Java 程序里transient關(guān)鍵字使用方法示例

    這篇文章主要為大家介紹了Java 程序里transient關(guān)鍵字使用方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Spring boot 配置多個(gè)redis的方法示例

    Spring boot 配置多個(gè)redis的方法示例

    這篇文章主要介紹了Spring boot 配置多個(gè)redis的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • 淺析RxJava處理復(fù)雜表單驗(yàn)證問(wèn)題的方法

    淺析RxJava處理復(fù)雜表單驗(yàn)證問(wèn)題的方法

    這篇文章主要介紹了RxJava處理復(fù)雜表單驗(yàn)證問(wèn)題的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-06-06
  • Lucene fnm索引文件格式源碼解析

    Lucene fnm索引文件格式源碼解析

    這篇文章主要為大家介紹了Lucene fnm索引文件格式源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 性能調(diào)優(yōu)之java服務(wù)器容器調(diào)優(yōu)詳解

    性能調(diào)優(yōu)之java服務(wù)器容器調(diào)優(yōu)詳解

    這篇文章主要介紹了java服務(wù)器容器調(diào)優(yōu),如果接口響應(yīng)時(shí)間超過(guò)了既定數(shù)據(jù),項(xiàng)目支撐不了這么大的請(qǐng)求,就需要對(duì)項(xiàng)目以及項(xiàng)目接口進(jìn)行數(shù)據(jù)庫(kù)、容器、緩存等方面的調(diào)優(yōu),文章中有詳細(xì)的代碼示例,需要的朋友可以參考一下
    2023-04-04
  • java:無(wú)法訪問(wèn)org.springframework.boot.SpringApplication問(wèn)題

    java:無(wú)法訪問(wèn)org.springframework.boot.SpringApplication問(wèn)題

    這篇文章主要介紹了java:無(wú)法訪問(wèn)org.springframework.boot.SpringApplication問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08

最新評(píng)論