详解原生Spring当中的额外功能开发MethodBeforeAdvice与MethodInterceptor接口!

news2024/11/19 19:37:18

 😉😉 学习交流群:

✅✅1:这是孙哥suns给大家的福利!

✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料

🥭🥭3:QQ群:583783824   📚📚  工作微信:BigTreeJava 拉你进微信群,免费领取!

🍎🍎4:本文章内容出自上述:Spring应用课程!💞💞

💞💞5:以上内容,进群免费领取呦~ 💞💞💞💞

一:额外功能

1:MethodBeforeAdvice

        额外功能实现了MethodBeforeAdvice接口,实现这个接口就需要实现这个接口当中的before方法,他的作用就是让额外功能运行在原始方法之前,这就是这个before方法的作用,before方法里边有着三个参数,method,Object[],Object,第一个参数method代表的就是要增加的目标方法或者叫原始方法,如何此时要增加的方法是login方法,那么Method代表的就是login方法,这个Method是变化的,Object[]代表的是原始方法的参数,Object对应的是原始对象,代表的是原始类或者目标类的实例。我们怎么证明这个事呢?可以通过debug来进行测试

        methodbeforeAdvice这个接口核心的作用就是保证。额外功能运行在原始方法执行之前,进行额外功能操作。

        MethodBeforeAdvice中before方法中的三个参数如何使用呢?
        作为一个接口所规定的接口方法参数我们不一定都得用,根据实际情况进行使用就行。举例来讲:前面我们在学servlet的时候,servlet规定了一个方法,service方法,这个方法有两个参数httpRequest,httpResponse这两个参数,servlet这个接口为我们提供了这样的方法,在我们后续的使用的过程当中,我们没有使用过后边的参数。

        例如我们只用来接收客户端的请求参数,直接使用request这个参数就好了,如果我们使用servlet是进行页面响应的,那么我们使用response这个参数就好了,使用这个参数获取输出流输出流进行页面响应。通过before方法的参数在实战中,会根据需要进行使用。

2:MethodInterceptor

        MethodInterceptor 方法拦截器。这个接口是完成额外功能实现的时候的第二个接口。这个接口和MethodBeforeAdvice有什么区别呢?MethodBeforeAdvice只能运行在原始方法之前,相对来讲,功能单一。

       MethodInterceptor  这个的接口的实现类的方法可以运行在原始方法执行之前,也可以运行在执行方法的执行之后,这个功能更加的强大一点,所以在实际过程中我们更多的使用的是MethodInterceptor这个接口,下面的这个:

/**
 * @Auther: DaShu
 * @Date: 2021/6/21 20:12
 * @Description:
 */
public class Around implements MethodInterceptor {
    @Override
    //这个接口的方法是有返回值的这也就解释了spring的注解开发的aop是Around方法里边的返回值是Object类型的
    //这个接口里边有一个invoke方法,我们也就把额外功能写入invoke当中,这个额外功能就能运行在原始方法之前,也能运行在原始方法之后。也可以运行在原始方法之前,之后。
    //原始方法怎么运行呢?这就需要知道这个方法的参数的含义:
    //这个方法的参数:这个就代表的事原始方法,底层相当于是对目标方法对象Method的一个更高级别的封装,可以认为他们两个设计相等的。methodInvocation.proceed()方法就代表目标方法执行了。
    //这个MthodInvocation就代表的事目标方法,而这里的methodinvocation.invoke就代表目标方法的运行。
    //到这:讲清楚了原始方法的运行是怎么回事的,
    //这个方法的返回值:这个返回值的原因在于实现接口的时候,接口按照接口返回值的类型,invoke方法有返回值 ,这里的Object
    //代表的就是原始方法执行之后的返回值,所以这个方法必须有一个Object,如果原始方法的返回值是void,那么我们返回一个null就行了。
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        return null;
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="userService" class = "com.pactera.spring.proxy.UserServiceImpl"/>
    <bean id="orderService" class = "com.pactera.spring.proxy.OrderServiceImpl"/>
<!--    <bean id="before" class="com.pactera.spring.dynamic.Before"/>-->
    <bean id = "around" class = "com.pactera.spring.dynamic.Around"/>
    <aop:config>
        <!--这个标签就是用来定义切入点的,expression这个是切入点表达式,代表所有的方法都要加上这个额外功能-->
        <!--所有的方法,都作为切入点作为额外功能。-->
        <aop:pointcut id="pc" expression="execution(* *(..))"/>
        <!--组装,组长的目的就是为了把切入点与额外的功能进行整合-->
        <aop:advisor advice-ref="around" pointcut-ref="pc"/>
    </aop:config>
</beans>
  /*
     * @Target: 用于测试Arround方法
     * @Author: DaShu
     * @Date: 2021/6/21 20:53
     * @Result:
     */
    @Test
    public void test3(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext3.xml");
        com.pactera.spring.proxy.OrderServcie orderService = (com.pactera.spring.proxy.OrderServcie)ctx.getBean("orderService");
        orderService.showOrder();
        //...........................这里是额外功能...............................
        //OrderServiceImpl.showOrder
        //-------------------------------这里还是额外功能----------------------------------------
    }


        总结:MehtodInterceptor这个接口的额外功能就是实现这接口的类被Spring创建的对象会被视为代理对象,实现并重写的方法invoke方法中书写额外功能,额外功能可以在目标方法前执行,可以在目标方法后执行,这是一种环绕执行的手段,很常用。

        总结2:让额外功能运行在原始方法执行之后执行,这就是废话。
        总结2:让额外功能运行在原始方法执行之前后执行,这也是废话。
        总结3:什么样的额外功能在方法的运行之前和运行之后都要添加呢?
       (日志,事务,性能分析等等。如图:

        还有一个额外功能不拘于之前之后,是运行在原始方法抛出异常的时候。

        额外功能执行在原始方法抛出异常的时候,这样的话,我们就在原始方法抛出异常的时候,在这个invoke当中的proceed方法周围进行trycatch,将异常进行捕获,捕获之后,将额外功能写到catch的代码快中就行了。

package com.pactera.spring.dynamic;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
 * @Auther: DaShu
 * @Date: 2021/6/21 20:12
 * @Description:
 */
public class Around implements MethodInterceptor {
    @Override
    //这个接口的方法是有返回值的这也就解释了spring的注解开发的aop是Around方法里边的返回值是Object类型的
    //这个接口里边有一个invoke方法,我们也就把额外功能写入invoke当中,这个额外功能就能运行在原始方法之前,也能运行在原始方法之后。也可以运行在原始方法之前,之后。
    //原始方法怎么运行呢?这就需要知道这个方法的参数的含义:
    //这个方法的参数:这个就代表的事原始方法,底层相当于是对目标方法对象Method的一个更高级别的封装,可以认为他们两个设计相等的。methodInvocation.proceed()方法就代表目标方法执行了。
    //这个MthodInvocation就代表的事目标方法,而这里的methodinvocation.invoke就代表目标方法的运行。
    //到这:讲清楚了原始方法的运行是怎么回事的,
    //这个方法的返回值:这个返回值的原因在于实现接口的时候,接口按照接口返回值的类型,invoke方法有返回值 ,这里的Object
    //代表的就是原始方法执行之后的返回值,所以这个方法必须有一个Object,如果原始方法的返回值是void,那么我们返回一个null就行了。
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println("...........................这里是额外功能...............................");
        Object proceed = null;
        try {
            proceed = methodInvocation.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("-------------------------------这里还是核心功能------------------------");
        }
        System.out.println("-------------------------------这里还是额外功能----------------------------------------");
        return proceed;
    }
}


        MethodInterceptor中的可以以影响原始方法中的返回值,我们在添加功能的时候我们可以获取到原始方法的返回值,然后我们可以把原始方法的返回值进行修改,这样就达到了修改的目的。
        其实你看Spring的这个Aop确实挺强大的,但是呢,前提是你得按照他的Aop的4个方法和步骤进行实现才行,最基本的附加功能类和目标类必须得是Spring进行创建的吧,切入点也得定义把,然后也得组装把,只有这样才能搞出来这个Aop。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1269742.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论文学习-Attention Is All You Need

Attention Is All You Need 目前暂时不会用到&#xff0c;大概了解一下即可。 Recurrent model 序列化的计算方式&#xff0c;难以并行&#xff0c;随着序列的增长&#xff0c;以前的记忆会逐渐丢失。而Attention机制可以观察到句子中所有的信息&#xff0c;不受距离影响&…

国密加密工业路由器 数据安全升级

国密加密工业路由器&#xff0c;简称国密加密路由器&#xff0c;是指遵循“商用密码管理规范”中规定的国家商用密码算法&#xff0c;采用国密加密芯片和密码算法的专业路由器。相比-般路由器&#xff0c;国密加密路由器具有更高级别的加密保护&#xff0c;可以有效提高数据传输…

线性表——(2)线性表的顺序存储及其运算的实现

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 看到美好&#xff0c;感受美好&a…

Java微服务框架 HP-SOA 1.0.5 — 完整支持 Spring Cloud 和 Dubbo

HP-SOA 功能完备&#xff0c;简单易用&#xff0c;高度可扩展的Java微服务框架。 项目主页 : https://www.oschina.net/p/hp-soa下载地址 : https://github.com/ldcsaa/hp-soa开发文档 : https://gitee.com/ldcsaa/hp-soa/blob/master/README.mdQQ Group: 44636872, 66390394…

SQL语法实践(三):一些问题

Q:What’s the difference between INNER JOIN, LEFT JOIN, RIGHT JOIN and F ULL JOIN? [duplicate] A:点击跳转链接到原文 There are different types of joins available in SQL: INNER JOIN: returns rows when there is a match in both tables. LEFT JOIN: returns al…

J2EE征程——第一个纯servletCURD

第一个纯servletCURD 前言在此之前 一&#xff0c;概述二、CURD1介绍2查询并列表显示准备实体类country编写 CountryListServlet配置web.xml为web应用导入mysql-jdbc的jar包 3增加准备增加的页面addc.html编写 CAddServlet配置web.xml测试 4删除修改CountryListServlet&#xf…

[Docker]十二.Docker consul集群搭建、微服务部署,Consul集群+Swarm集群部署微服务实战

一.Docker consul集群搭建 Consul 是 Go 语言写的开源的服务发现软件&#xff0c; Consul 具有 服务发现、健康检查、 服务治理、微服务熔断处理 等功能,在微服务中讲过如何搭建consul集群&#xff0c;接下来看看在 Dokcer 中如何去创建搭建consul 集群 1.linux上面部署consul集…

【Flutter】graphic图表实现tooltip一段时间后自动隐藏

概述 graphic图表中提供了自定义tooltip的事件&#xff0c;可通过selections中on和clear配置手势选项和可识别设备&#xff0c;默认情况下tooltip需要双击隐藏&#xff0c;但这并不符合我们的需求。通过调研发现&#xff0c;若想实现tooltip隔几秒后隐藏&#xff0c;可通过Str…

从0开始学习JavaScript--JavaScript 中 `let` 和 `const` 的区别及最佳实践

在JavaScript中&#xff0c;let 和 const 是两个用于声明变量的关键字。尽管它们看起来很相似&#xff0c;但它们之间有一些重要的区别。本篇博客将深入探讨 let 和 const 的用法、区别&#xff0c;并提供一些最佳实践&#xff0c;以确保在代码中正确使用它们。 let 和 const …

36 - 电商系统表设计优化案例分析

如果在业务架构设计初期&#xff0c;表结构没有设计好&#xff0c;那么后期随着业务以及数据量的增多&#xff0c;系统就很容易出现瓶颈。如果表结构扩展性差&#xff0c;业务耦合度将会越来越高&#xff0c;系统的复杂度也将随之增加。这一讲我将以电商系统中的表结构设计为例…

iOS NSDate的常用API

目录 一、创建日期 1.获取当前时间 2.当前时间指定秒数之后/前的时间 3.指定日期之后/后的时间 4.2001年之后/前指定秒数的时间 5.1970年之后/后指定秒数的时间 二、初始化日期 1.init 2.时间间指定秒数的时间 3.指定时间指定秒数之前/后的时间 4.2001年指定秒数之后…

网络相关-面试高频

网络 当前的应用系统主要分两大类&#xff0c;一类是C/S&#xff08;Client/Server&#xff09;客户端/服务器架构的&#xff0c;一类是B/S&#xff08;Browser/Server&#xff09;浏览器/服务器架构的[3]&#xff0c;例如&#xff1a;PC上安装的QQ程序是典型的C/S架构中的客户…

C# Onnx 阿里达摩院开源DAMO-YOLO目标检测

效果 模型信息 Inputs ------------------------- name&#xff1a;images tensor&#xff1a;Float[1, 3, 192, 320] --------------------------------------------------------------- Outputs ------------------------- name&#xff1a;output tensor&#xff1a;Float…

人工智能-优化算法之动量法

对于嘈杂的梯度&#xff0c;我们在选择学习率需要格外谨慎。 如果衰减速度太快&#xff0c;收敛就会停滞。 相反&#xff0c;如果太宽松&#xff0c;我们可能无法收敛到最优解。 泄漏平均值 小批量随机梯度下降作为加速计算的手段。 它也有很好的副作用&#xff0c;即平均梯度…

HMM(Hidden Markov Model)详解——语音信号处理学习(三)(选修一)

参考文献&#xff1a; Speech Recognition (Option) - HMM哔哩哔哩bilibili 2020 年 3月 新番 李宏毅 人类语言处理 独家笔记 HMM - 6 - 知乎 (zhihu.com) 隐马尔可夫&#xff08;HMM)的解码问题维特比算法 - 知乎 (zhihu.com) 本次省略所有引用论文 目录 一、介绍 二、建模单…

解决uview中uni-popup弹出层不能设置高度问题

开发场景&#xff1a;点击条件筛选按钮&#xff0c;在弹出的popup框中让用户选择条件进行筛选 但是在iphone12/13pro展示是正常&#xff0c;但是切换至其他手机型号就填充满了整个屏幕&#xff0c;需要给这个弹窗设置一个固定的高度 iphone12/13pro与其他型号手机对比 一开始…

关于使用若依,并不会自动分页的解决方式

关于使用若依,并不会自动分页的解决方式 如果只是单纯的使用一次查询list,并不会触发这个bug 例如: 但是我们如果对里面的数据进行调整修改的话就会触发这个bug 例如: 此时可以看到我对数据进行了转换!!!,这时如果超出数据10条,实际我们拿到的永远是10条,具体原因这里就不展…

ora.LISTENER.lsnr状态为Not All Endpoints Registered

客户的监控反馈有个监听无法连接&#xff0c;登录环境检查发现ora.LISTENER.lsnr的状态为Not All Endpoints Registered&#xff0c;如下 [rootdb2 ~]# crsctl status res -t -------------------------------------------------------------------------------- NAME …

什么是requestIdleCallback?和requestAnimationFrame有什么区别?

什么是requestIdleCallback? 我们都知道React 16实现了新的调度策略(Fiber), 新的调度策略提到的异步、可中断&#xff0c;其实就是基于浏览器的 requestIdleCallback和requestAnimationFrame两个API。 在 JavaScript 中&#xff0c;requestIdleCallback 是一个用于执行回调函…