亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

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

Demo實現(xiàn)

引入依賴

        <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,將不會封裝返回結(jié)果)

/**
 * @interface自定義注解
 * @Target: 注解的作用目標(biāo)  PARAMETER:方法參數(shù)   METHOD:方法 TYPE:類、接口
 *
 * @Retention:注解的保留位置  RUNTIME  種類型的Annotations將被JVM保留,
 *
 * 能在運行時被JVM或其他使用反射機制的代碼所讀取和使用
 */
@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)

/**
 * 通用返回類
 *
 * @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());
    }
}

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

Controller實現(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é)果

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述


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

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

相關(guān)文章

  • Java中?equals?重寫時為什么一定也要重寫?hashCode

    Java中?equals?重寫時為什么一定也要重寫?hashCode

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

    AndroidStudio無法新建Java工程的簡單解決辦法

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

    MyBatisPlus中@TableField注解的基本使用

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

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

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

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

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

    Spring中Properties的配置方式

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

    RedisKey的失效監(jiān)聽器KeyExpirationEventMessageListener問題

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

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

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

    解決在for循環(huán)中remove list報錯越界的問題

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

    log4j使用詳細(xì)解析

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

最新評論