返回顶部
首页 > 资讯 > 后端开发 > Python >Spring使用AOP完成统一结果封装实例demo
  • 221
分享到

Spring使用AOP完成统一结果封装实例demo

Spring使用AOP统一结果封装Spring统一结果封装SpringAOP封装 2023-02-06 12:02:28 221人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录spring使用aop完成统一结果封装Demo实现Spring使用AOP完成统一结果封装 起因:自己写项目的时候忍受不了每个方法都要写一个retrun Result.succes

Spring使用AOP完成统一结果封装

起因:自己写项目的时候忍受不了每个方法都要写一个retrun Result.success();retrun Result.error();,同时想到项目运行时异常的统一捕捉处理,于是我就在想有没有一种方法能够快捷有效的实现统一返回结果格式的方法。同时也能够比较方便的设置各种参数方便使用,于是我就想到AOP。

Demo实现

引入依赖

        <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,将不会封装返回结果)


@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;

    
    private final String message;

    
    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 用于定义统一返回结果结构


@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());
    }
}

切面实现

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;


@Slf4j
@Aspect
@Component
public class ResulyAspect {
    @Pointcut("execution(* com.study.project.controller.*..*(..))")
    public void pointAspect() {
    }

    
    @Around("pointAspect()")
    public Object doAfter(ProceedingJoinPoint joinPoint) throws Throwable {
        // 转换为method
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        // 包装结果
        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;
        }
        // 设置了不需要包装的接口
        NoResult noResult = method.getAnnotation(NoResult.class);
        if (noResult == null) {
            noResult = method.getDeclarinGClass().getAnnotation(NoResult.class);
        }
        if (noResult != null) {
            return result;
        }
        // 非restful风格接口不需要包装
        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()”) 表示此方法应用于 pointAspect切面,@Around 表示在切点的前后都执行此方法
这中间其实还有一个小插曲,我本来想用JoinPoint类,并使用@After后置通知的方法,结果我发现我在后置通知的JoinPoint里面无法获取方法的接口result,所以后面就换了ProceedingJoinPoint类,这个类有一个特殊的方法proceed()可以直接获取方法的返回值。

Controller实现

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


@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;
    }
}

结果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


到此为止,我们就实现了统一的结果封装。

到此这篇关于Spring使用AOP完成统一结果封装的文章就介绍到这了,更多相关Spring使用AOP统一结果封装内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Spring使用AOP完成统一结果封装实例demo

本文链接: https://lsjlt.com/news/194351.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作