(WebFlux)001、如何自定义注解实现功能

一、背景

最近在项目又在压测,但基于Http请求类型的校验过多,已有想法把Http请求换成Spring中的WebClient,但是由于不是原配(SpringWebFlux + WebClient),如果采用WebClent….block()这样的实现方式,阻塞获取结果,老是觉得别扭,所以就想把SpringMVC换成SpringWebFlux(新手上路),大胆尝试,直接发车。

现在把换的过程中的问题和解决方式列出来,供大家参考。

SpringBoot版本号: 2.6.10

二、正文

在使用SpringMVC实现业务逻辑时,我们经常会采用一些自定义注解,通过自定义注解实现访问URL过滤、鉴权等一些列功能。但是在WebFlux中如何实现呢?

在MVC中,我们一般直接实现 HandlerInterceptor,然后实现 HandlerInterceptor#preHandle()方法即可,然后在其中实现自己的逻辑。代码如下、

先实现自定义注解:

/**
 * 校验权限
 *
 * @author fattycal@qq.com
 * @since 2022/7/24
 */
@Target({ElementType.TYPE, ElementType.METHOD}) // 可用于方法和类上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CheckPermission {

    boolean check() default true;
}

为什么要标记在方法和类上呢? 那是因为有可能某一个类的方法都需要CheckPermission 或者都不check,直接标记在类上就省事了。

接下来是实现拦截器:

/**
 * 拦截器
 *
 * @author fattycal@qq.com
 * @since 2022/7/24
 */
@Component
public class CheckPermissionInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        if (handler instanceof HandlerMethod) {
            HandlerMethod methodHandle = (HandlerMethod) handler;
            CheckPermission permission = methodHandle.getMethodAnnotation(CheckPermission.class);
            if (Objects.isNull(permission)) {
                // handler 所有bean 上面寻找
                permission = AnnotationUtils.findAnnotation(methodHandle.getBeanType(), CheckPermission.class);
            }

            if (Objects.nonNull(permission)) {
                // TODO  do something..

            }
        }
        return true;
    }
}

当我们在当前Handler上没有找到注解的的时候,我们就去所在类上寻找,判断是否需要校验。偷鸡,减少代码注解标记量(心理美滋滋)。

MVC的实现方式对我们来说可谓是手到擒来,闭着眼睛也能把代码敲完(吹嘘居多…),这么常见、基础、重要的功能,在WebFlux中是如何实现的呢?

/**
 * WebFlux实现方案
 *
 * @author fattycal@qq.com
 * @since 2022/7/24
 */
@Component
public class CheckPermissionWebFilter implements WebFilter {

    @Autowired
    // 关键,通过RequestMappingHandlerMapping 我们可以获取到MethodHandler
    private RequestMappingHandlerMapping handlerMapping;

    @Override
    public Mono filter(ServerWebExchange exchange, WebFilterChain chain) {
        return handlerMapping.getHandler(exchange).switchIfEmpty(chain.filter(exchange))
                .flatMap(handler -> {
                            // 熟悉的味道,将handler转换成HandlerMethod
                            if (handler instanceof HandlerMethod) {
                                HandlerMethod methodHandle = (HandlerMethod) handler;
                                CheckPermission permission = methodHandle.getMethodAnnotation(CheckPermission.class);
                                if (Objects.isNull(permission)) {
                                    // handler 所有bean 上面寻找
                                    permission = AnnotationUtils.findAnnotation(methodHandle.getBeanType(), CheckPermission.class);
                                }

                                if (Objects.nonNull(permission)) {
                                    // TODO  do something..

                                }
                            }
                            return chain.filter(exchange);
                        }
                );
    }
}

可以看到,在实现过程中,最关键的是要知道有 org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping这个类,知道之后,我们就可以通过其获取到Handler。拿到Handler后就可以按照我们自己的套路来实现具体的业务逻辑了。

通过对比MVC和WebFlux的实现方式来看,Spring对两种都做了比较好的支持,都是通过获取到HandlerMethod,然后在对具体的逻辑处理。对比后发现,代码相似度达到80%~90%。这也要求我们要做的可能是更多的知道其有的API,这样可以减少我们在对项目做转换时带来的时间成本问题。至于实现,我们可以在熟悉使用时,一步步探索,挖掘实现逻辑,提高知识存储量。

三、总结

尝试新东西的时候是一个不断探索,学习的过程。多看,多搜,多学。

Original: https://www.cnblogs.com/lifacheng/p/16514582.html
Author: 编号94530
Title: (WebFlux)001、如何自定义注解实现功能

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/615257/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • java对形参操作能否改变实参

    这个问题其实以前就断断续续的纠结过,这次机缘巧合之下稍微深入的理解了这个问题。 这里的问题是:在主方法里创建了N个一般属性,将这些属性传递给其他方法,当 其他方法改变了传递来的形参…

    Java 2023年6月7日
    067
  • JAVA复习总体大纲

    1 java基础. [1].变量— 数据类型 变量名=值;数据类型:1.基本数据类型. byte[1字节] short[2字节] int[4字节] long[8字节] …

    Java 2023年6月5日
    070
  • Java中如何快捷的创建不可变集合

    在Java 9中又新增了一些API来帮助便捷的创建不可变集合,以减少代码复杂度。 常规写法 以往我们创建一些不可变集合的时候,通常是这样写的: // 不可变的Set Set set…

    Java 2023年6月9日
    081
  • WindowsOS下Nginx+PHP环境配置

    PHP 配置 php\ext下修改php.ini-development文&#x4E…

    Java 2023年5月30日
    077
  • Java通过PriorityQueue构建大顶堆和小顶堆

    Comparator comparator = Comparator.comparing(Obj::getValue); 小顶堆: PriorityQueue minHeap = …

    Java 2023年5月29日
    078
  • 合并链表

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月5日
    077
  • Cit 入门操作笔记

    Git操作入门 Git 是一个快速、可扩展的 分布式版本控制系统 ,它具有极为丰富的命令集,对内部系统提供了高级操作和完全访问.Git与你熟悉的大部分版本控制系统的差别是很大的。相…

    Java 2023年6月15日
    069
  • 安装java jdk和eclipse和andorid环境

    目的是构建一个以eclipse为主体,可以创建java的windows窗口程序,android程序的开发环境。 1、下载jdk-18,目前最新版本。https://www.orac…

    Java 2023年5月29日
    067
  • SystemVerilog(6):线程通信

    1、线程 线程即独立运行的程序。 线程需要被触发,可以结束或者不结束。 在 module 中的 initial 和 always,都可以看做独立的线程,它们会在仿真 0 时刻开始,…

    Java 2023年5月30日
    097
  • Git回滚代码到某个commit(图文讲解 仅需2步)

    git log git reset –hard commited_id(就是唯一标识id) 执行步骤命令 仅需&#x…

    Java 2023年6月5日
    080
  • Hyperledger Fabric 2.x Java区块链应用

    一、说明 在上一篇文章中 《Hyperledger Fabric 2.x 自定义智能合约》 分享了智能合约的安装并使用 cli 客户端进行合约的调用;本文将使用 Java 代码基于…

    Java 2023年6月6日
    0106
  • 几种流行的AJAX框架jQuery,Mootools,Dojo,Ext JS的对比

    AJAX是 web2.0的基石,现在网上流行几种开源的AJAX框架,比如:jQuery,Mootools,Dojo,Ext JS等等,那么我们到底在什么情况下该使用那个框架? 让我…

    Java 2023年6月9日
    090
  • MYSQL5.7详细安装步骤

    0、更换yum源 1、打开 mirrors.aliyun.com,选择centos的系统,点击帮助 2、执行命令:yum install wget -y 3、改变某些文件的名称 m…

    Java 2023年6月7日
    0100
  • 针对Asp.net MVC SEO的几点建议

    1. 引言 SEO 即搜索引擎优化,很多web开发人员本应该熟悉,至少需要了解的一个知识点。像百度、必应等搜索引擎其实一直都在进化。但是有些优化的技巧可能在短时间内不变。 今天就给…

    Java 2023年6月5日
    064
  • redis命令操作list 和redis命令操作set&sortedset

    redis命令操作list 列表类型 list:可以添加一个元素列表的头部(左边)或者尾部(右边) 添加: lpush key value:将元素加入列表左边 rpush key …

    Java 2023年6月6日
    0106
  • java学习摘抄笔记mybaits2

    mybatis 第二天 高级映射 查询缓存 和 spring 整合 课程复习: mybatis 是什么? mybatis 是一人持久层框架,mybatis 是一个不完全的ORM 框…

    Java 2023年5月29日
    061
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球