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

news/2024/2/29 2:23:25

 😉😉 学习交流群:

✅✅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:*/@Testpublic 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。


https://www.xjx100.cn/news/3118874.html

相关文章

PTApt——2023年软件设计综合实践_7(数据结构)

6-1 递增的整数序列链表的插入 本题要求实现一个函数&#xff0c;在递增的整数序列链表&#xff08;带头结点&#xff09;中插入一个新整数&#xff0c;并保持该序列的有序性。 答案&#xff1a; 语言选C(gcc) List Insert(List L, ElementType X) {List tmp (List) mal…

flink源码分析之功能组件(四)-slotpool组件II

简介 本系列是flink源码分析的第二个系列&#xff0c;上一个《flink源码分析之集群与资源》分析集群与资源&#xff0c;本系列分析功能组件&#xff0c;kubeclient&#xff0c;rpc&#xff0c;心跳&#xff0c;高可用&#xff0c;slotpool&#xff0c;rest&#xff0c;metrics&…

FastApi接收不到Apifox发送的from-data字符串_解决方法

接收不到Apifox发送的from-data字符串_解决方法 问题描述解决方法弯路总结弯路描述纵观全局小结 问题描述 这里写了一个接口&#xff0c;功能是上传文件&#xff0c;接口参数是file文件和一个id字符串 gpt_router.post("/uploadfiles") async def create_upload_fi…

Web安全漏洞分析-XSS(中)

随着互联网的迅猛发展&#xff0c;Web应用的普及程度也愈发广泛。然而&#xff0c;随之而来的是各种安全威胁的不断涌现&#xff0c;其中最为常见而危险的之一就是跨站脚本攻击&#xff08;Cross-Site Scripting&#xff0c;简称XSS&#xff09;。XSS攻击一直以来都是Web安全领…

编程零基础算法 | 四、循环和选择结构——1572. 矩阵对角线元素的和

一、题目链接 1572. 矩阵对角线元素的和 二、题目简介 给你两个整数&#xff0c;n 和 start 。 数组 nums 定义为&#xff1a;nums[i] start 2*i&#xff08;下标从 0 开始&#xff09;且 n nums.length 。 请返回 nums 中所有元素按位异或&#xff08;XOR&#xff09;后…

vueRouter常用属性

vueRouter常用属性 basemodehashhistoryhistory模式下可能会遇到的问题及解决方案 routesprops配置(最佳方案) scrollBehavior base 基本的路由请求的路径 如果整个单页应用服务在 /app/ 下&#xff0c;然后 base 就应该设为 “/app/”,所有的请求都会在url之后加上/app/ new …

通过Python Flask快速构建应用程序

通过Python Flask快速构建应用程序 当你想要快速创建一个简单且轻量级的 Web 应用程序时&#xff0c;Python 的 Flask 框架是一个非常好的选择。Flask 提供了许多有用的功能和扩展&#xff0c;可以帮助你快速搭建一个可靠的 Web 应用程序。本文将向你介绍如何快速入门并开始使…

OpenCvSharpSlim画中文

github地址&#xff1a;https://github.com/AvenSun/OpenCvSharpSlim Slim Build of OpenCvSharp OpenCvSharpSlim This project provides the slim build of OpenCvSharp native library . Currently therere binary packages for OpenCvSharp 2.4.10, 3.4.20 ,4.8.0 and 4…