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

Spring使用AOP完成統(tǒng)一結(jié)果封裝實(shí)例demo

 更新時(shí)間:2023年02月06日 11:39:29   作者:ss無(wú)所事事  
這篇文章主要介紹了Spring使用AOP完成統(tǒng)一結(jié)果封裝,本文通過(guò)實(shí)現(xiàn)demo給大家詳細(xì)講解,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

Spring使用AOP完成統(tǒng)一結(jié)果封裝

起因:自己寫(xiě)項(xiàng)目的時(shí)候忍受不了每個(gè)方法都要寫(xiě)一個(gè)retrun Result.success();retrun Result.error();,同時(shí)想到項(xiàng)目運(yùn)行時(shí)異常的統(tǒng)一捕捉處理,于是我就在想有沒(méi)有一種方法能夠快捷有效的實(shí)現(xiàn)統(tǒng)一返回結(jié)果格式的方法。同時(shí)也能夠比較方便的設(shè)置各種參數(shù)方便使用,于是我就想到AOP。

Demo實(shí)現(xiàn)

引入依賴(lài)

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

自定義注解(NoResult.java 使用此注解的method,將不會(huì)封裝返回結(jié)果)

/**
 * @interface自定義注解
 * @Target: 注解的作用目標(biāo)  PARAMETER:方法參數(shù)   METHOD:方法 TYPE:類(lèi)、接口
 *
 * @Retention:注解的保留位置  RUNTIME  種類(lèi)型的Annotations將被JVM保留,
 *
 * 能在運(yùn)行時(shí)被JVM或其他使用反射機(jī)制的代碼所讀取和使用
 */
@Documented
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface NoResult {
}

ResultCode.class 用于定義Reponses返回碼

public enum ResultCode {
    SUCCESS(0, "操作成功", ""),
    ERROR(1, "操作失敗", "");

    private final int code;

    /**
     * 狀態(tài)碼信息
     */
    private final String message;

    /**
     * 狀態(tài)碼描述(詳情)
     */
    private final String description;

    ResultCode(int code, String message, String description) {
        this.code = code;
        this.message = message;
        this.description = description;
    }

    public int getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }

    public String getDescription() {
        return description;
    }
}

BaseResponse.java 用于定義統(tǒng)一返回結(jié)果結(jié)構(gòu)

/**
 * 通用返回類(lèi)
 *
 * @param <T>
 * @author Chengming.Zhang
 */
@Data
public class BaseResponse<T> implements Serializable {

    private int code;

    private T data;

    private String message;

    private String description;

    public BaseResponse(int code, T data, String message, String description) {
        this.code = code;
        this.data = data;
        this.message = message;
        this.description = description;
    }

    public BaseResponse(int code, T data, String message) {
        this(code, data, message, "");
    }

    public BaseResponse(int code, T data) {
        this(code, data, "", "");
    }

    public BaseResponse(ResultCode resultCode) {
        this(resultCode.getCode(), null, resultCode.getMessage(), resultCode.getDescription());
    }
    public BaseResponse(ResultCode resultCode, T data) {
        this(resultCode.getCode(), data, resultCode.getMessage(), resultCode.getDescription());
    }
}

切面實(shí)現(xiàn)

import com.study.project.annotation.NoResult;
import com.study.project.common.BaseResponse;
import com.study.project.common.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Method;

/**
 * @author Chengming.Zhang
 * @date 2023/2/5
 */
@Slf4j
@Aspect
@Component
public class ResulyAspect {
    @Pointcut("execution(* com.study.project.controller.*..*(..))")
    public void pointAspect() {
    }

    /**
     * 環(huán)繞通知
     *
     * @param joinPoint
     */
    @Around("pointAspect()")
    public Object doAfter(ProceedingJoinPoint joinPoint) throws Throwable {
        // 轉(zhuǎn)換為method
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        // 包裝結(jié)果
        return packageResult(joinPoint, method);
    }

    public Object packageResult(ProceedingJoinPoint joinPoint, Method method) throws Throwable {
        Class<?> returnType = method.getReturnType();
        Object result = joinPoint.proceed();
        // void不需要包裝
        if (returnType.equals(void.class) || returnType.equals(Void.class)) {
            return result;
        }
        // 設(shè)置了不需要包裝的接口
        NoResult noResult = method.getAnnotation(NoResult.class);
        if (noResult == null) {
            noResult = method.getDeclaringClass().getAnnotation(NoResult.class);
        }
        if (noResult != null) {
            return result;
        }
        // 非restful風(fēng)格接口不需要包裝
        RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
        GetMapping getMapping = method.getAnnotation(GetMapping.class);
        PostMapping postMapping = method.getAnnotation(PostMapping.class);
        DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
        PutMapping putMapping = method.getAnnotation(PutMapping.class);
        PatchMapping patchMapping = method.getAnnotation(PatchMapping.class);
        if (requestMapping != null || getMapping != null || postMapping != null || deleteMapping != null || putMapping != null || patchMapping != null) {
            if (result == null) {
                return new BaseResponse(ResultCode.ERROR);
            } else {
                if (result instanceof BaseResponse) {
                    BaseResponse baseResponse = (BaseResponse) result;
                    return baseResponse;
                } else {
                    return new BaseResponse(ResultCode.SUCCESS, result);
                }
            }
        } else {
            return result;
        }
    }
}

代碼分析

@Pointcut 注解用于定義一個(gè)切面,上述代碼中的切面表示com.study.project.controller包及其子包下的所有類(lèi)和方法
@Around(“pointAspect()”) 表示此方法應(yīng)用于 pointAspect切面,@Around 表示在切點(diǎn)的前后都執(zhí)行此方法
這中間其實(shí)還有一個(gè)小插曲,我本來(lái)想用JoinPoint類(lèi),并使用@After后置通知的方法,結(jié)果我發(fā)現(xiàn)我在后置通知的JoinPoint里面無(wú)法獲取方法的接口result,所以后面就換了ProceedingJoinPoint類(lèi),這個(gè)類(lèi)有一個(gè)特殊的方法proceed()可以直接獲取方法的返回值。

Controller實(shí)現(xiàn)

import com.study.project.annotation.NoResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Chengming.Zhang
 * @date 2023/2/4
 */
@RestController
public class TestController {

    @RequestMapping("/test1")
    public Object test1(){
        return "test1";
    }

    @NoResult
    @RequestMapping("/test2")
    public Object test2(){
        return "test2";
    }

    @RequestMapping("/test3")
    public Object test3(){
        return null;
    }
}

結(jié)果

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述


到此為止,我們就實(shí)現(xiàn)了統(tǒng)一的結(jié)果封裝。

到此這篇關(guān)于Spring使用AOP完成統(tǒng)一結(jié)果封裝的文章就介紹到這了,更多相關(guān)Spring使用AOP統(tǒng)一結(jié)果封裝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中?equals?重寫(xiě)時(shí)為什么一定也要重寫(xiě)?hashCode

    Java中?equals?重寫(xiě)時(shí)為什么一定也要重寫(xiě)?hashCode

    這篇文章主要介紹了Java中?equals?重寫(xiě)時(shí)為什么一定也要重寫(xiě)?hashCode,equals?方法和?hashCode?方法是?Object?類(lèi)中的兩個(gè)基礎(chǔ)方法,它們共同協(xié)作來(lái)判斷兩個(gè)對(duì)象是否相等,所以之間到底有什么聯(lián)系呢,接下來(lái)和小編一起進(jìn)入文章學(xué)習(xí)該內(nèi)容吧
    2022-05-05
  • AndroidStudio無(wú)法新建Java工程的簡(jiǎn)單解決辦法

    AndroidStudio無(wú)法新建Java工程的簡(jiǎn)單解決辦法

    AS創(chuàng)建java工程是非常麻煩的,AS沒(méi)有提供直接創(chuàng)建java工程的方法且常常無(wú)法新建,這篇文章主要給大家介紹了關(guān)于AndroidStudio無(wú)法新建Java工程的簡(jiǎn)單解決辦法,需要的朋友可以參考下
    2024-06-06
  • MyBatisPlus中@TableField注解的基本使用

    MyBatisPlus中@TableField注解的基本使用

    這篇文章主要介紹了MyBatisPlus中@TableField注解的基本使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • java音頻播放示例分享(java如何播放音頻)

    java音頻播放示例分享(java如何播放音頻)

    java如何播放音頻?下面的代碼就介紹了java音頻播放示例,需要的朋友可以參考下
    2014-04-04
  • java.net.MalformedURLException異常的解決方法

    java.net.MalformedURLException異常的解決方法

    下面小編就為大家?guī)?lái)一篇java.net.MalformedURLException異常的解決方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • Spring中Properties的配置方式

    Spring中Properties的配置方式

    這篇文章主要介紹了Spring中Properties的配置方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • RedisKey的失效監(jiān)聽(tīng)器KeyExpirationEventMessageListener問(wèn)題

    RedisKey的失效監(jiān)聽(tīng)器KeyExpirationEventMessageListener問(wèn)題

    這篇文章主要介紹了RedisKey的失效監(jiān)聽(tīng)器KeyExpirationEventMessageListener問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • java之super關(guān)鍵字用法實(shí)例解析

    java之super關(guān)鍵字用法實(shí)例解析

    這篇文章主要介紹了java之super關(guān)鍵字用法實(shí)例解析,較為詳細(xì)的分析了super關(guān)鍵字的用法及內(nèi)存分布,需要的朋友可以參考下
    2014-09-09
  • 解決在for循環(huán)中remove list報(bào)錯(cuò)越界的問(wèn)題

    解決在for循環(huán)中remove list報(bào)錯(cuò)越界的問(wèn)題

    這篇文章主要介紹了解決在for循環(huán)中remove list報(bào)錯(cuò)越界的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • log4j使用詳細(xì)解析

    log4j使用詳細(xì)解析

    Log4j 除了可以記錄程序運(yùn)行日志信息外還有一重要的功能就是用來(lái)顯示調(diào)試信息。下面通過(guò)本文給大家介紹log4j使用詳細(xì)解析,感興趣的朋友一起看看吧
    2017-10-10

最新評(píng)論