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

 😉😉 学习交流群:

✅✅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。

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

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

相关文章

Redis对象系统

前言 在Redis中有许多数据结构&#xff0c;比如&#xff1a;简单动态字符串(SDS)&#xff0c;双端链表&#xff0c;字典&#xff0c;压缩列表&#xff0c;整数集合等。 Redis并没有直接使用这些数据结构来实现键值对数据库&#xff0c;而是基于这些数据结构创建了一个对象系统。…

vue项目运行时,报错:ValidationError: webpack Dev Server Invalid Options

在运行vue项目中&#xff0c;遇到报错&#xff1a;ValidationError: webpack Dev Server Invalid Options&#xff0c;如下图截图&#xff1a; 主要由于vue.config.js配置文件错误导致的&#xff0c;具体定位到proxy配置代理不能为空&#xff0c;导致运行项目报错&#xff0c;需…

SQL中 JOIN 的两种连接类型:内连接(自然连接、自连接、交叉连接)、外连接(左外连接、右外连接、全外连接)

SQL中 JOIN 的两种连接类型&#xff1a;内连接&#xff08;自然连接、自连接、交叉连接&#xff09;、外连接&#xff08;左外连接、右外连接、全外连接&#xff09; 1. 自然连接&#xff08;natural join&#xff09;&#xff08;内连接&#xff09; 学生表 mysql> sele…

连接备份1128

深度学习—分类识别篇&#xff1a;http://tr.daheng-imaging.com/watch/1050636http://tr.daheng-imaging.com/watch/1050636 深度学习—目标检测篇&#xff1a;http://tr.daheng-imaging.com/watch/1101141http://tr.daheng-imaging.com/watch/1101141 深度学习—缺陷分割篇&a…

Oracle研学-基础操作

学自B站黑马程序员笔记 一 创建表空间(创建数据文件) 创建表空间同时会创建一个数据文件(下面5行应该是一句话)&#xff0c;表空间在PLSQL的Object的tablespace中可以看到 create tablespace waterboss //创建表空间 datafile c:\waterboss.dbf //创建表空间对应的…

Chrome显示分享按钮

分享按钮不见了&#xff01; Chrome://flags Chrome Refresh 2023 Disabled 左上角的标签搜索会到右上角。

MATLAB实战 | APP设计

01、应用实战 【例1】生成一个用于观察视点仰角和坐标轴着色方式对三维图形显示效果影响的App&#xff0c;界面如图1所示。界面右上部的列表框用于选择绘图数据、切换按钮组用于选择绘图方法&#xff0c;中间的旋钮用于设置视点方位角和仰角&#xff0c;右下部的分档旋钮用于设…

Thrift RPC Java、Go、PHP使用例子

文章目录 1、Thrift RPC介绍1.1、Protocol 支持的数据传输协议1.2、Transport 支持的数据传输方式1.3、Server 支持的服务模型1.4、IDL语法数据类型1.5、开发步骤 2、接口定义文件2.1、创建接口定义文件2.2、生成对应平台语言代码2.2.1、下载生成工具2.2.2、生成各平台语言代码…

Android系统分析

Android工程师进阶第八课 AMS、WMS和PMS 一、Binder通信 【Android Framework系列】第2章 Binder机制大全_android binder-CSDN博客 Android Binder机制浅谈以及使用Binder进行跨进程通信的俩种方式&#xff08;AIDL以及直接利用Binder的transact方法实现&#xff09;_bind…

基于web宠颐生宠物医院系统设计与实现

基于web宠颐生医院系统开发与实现 摘要&#xff1a;时代飞速发展&#xff0c;网络也飞速发展&#xff0c;互联网许多的行业都可以用互联网实现了&#xff0c;互联网已经成为了人们生活中重要的一部分&#xff0c;或多或少的影响着我们的生活&#xff0c;互联网在给我带了方便的…

【Node.js】笔记整理 2 - 常用模块

写在最前&#xff1a;跟着视频学习只是为了在新手期快速入门。想要学习全面、进阶的知识&#xff0c;需要格外注重实战和官方技术文档&#xff0c;文档建议作为手册使用 系列文章 【Node.js】笔记整理 1 - 基础知识【Node.js】笔记整理 2 - 常用模块【Node.js】笔记整理 3 - n…

Linux mesg命令详解:如何设置终端机的写入权限并阻止或允许其他用户的信息显示(附实例教程和注意事项)

Linux mesg命令介绍 Linux mesg命令用于设置终端机的写入权限。当mesg设置为y时&#xff0c;其他用户可以利用write指令将信息直接显示在您的屏幕上。如果设置为n&#xff0c;则不允许其他用户将信息直接显示在你的屏幕上。 Linux mesg命令适用的Linux版本 mesg命令在大多数…

ESP32通过IIC同时驱动mpu6050和OLED

mpu6050 //安装库MPU6050_tockn1.5.2 //接线 供电3.3V scl--引脚22 sda----引脚21 #include <MPU6050_tockn.h> #include <Wire.h>MPU6050 mpu6050(Wire);void setup() {Serial.begin(115200);Wire.begin();mpu6050.begin();mpu6050.calcGyroOffsets(true);de…

Bert-VITS2本地部署遇到的错误

关于Bert-VITS2本地部署遇到的错误 1、在下载python中相关依赖时报错 building ‘hdbscan._hdbscan_tree’ extension error: Microsoft Visual C 14.0 or greater is required. Get it with “Microsoft C Build Tools”: https://visualstudio.microsoft.com/visual-cpp-bu…

【安全-SSH】SSH安全设置

今天发现自己的公有云服务器被攻击了 然后查看了登录日志&#xff0c;如上图 ls -sh /var/log/secure vim /var/log/secure然后增加了安全相关的设置 具体可以从以下方面增加安全性&#xff1a; 修改默认SSH端口公有云修改安全组策略及防火墙端口设置登录失败次数锁定用户及…

SH文件介绍

SH文件介绍 介绍SH文件示例执行SH文件具体用法 介绍 SH文件通常指的是 Shell 脚本文件&#xff0c;文件后缀名为.sh&#xff0c;其中包含一系列要由操作系统的命令解释器执行的命令。 在 Unix 和类 Unix 操作系统中&#xff0c;通常使用 Bourne Shell&#xff08;sh&#xff…

RabbitMQ消息模型之Routing-Direct

Routing Direct 在Fanout模式中&#xff0c;一条消息&#xff0c;会被所有订阅的队列都消费。但是在某些场景下&#xff0c;我们希望不同的消息被不同的队列消费。这时就要用到Direct类型的Exchange。 在Direct模型下&#xff1a; 队列与交换机的绑定&#xff0c;不能是任意…

刷题笔记(第九天)

1. 求最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀&#xff0c;返回空字符串 “”。 示例 1&#xff1a; 输入&#xff1a;strs [“flower”,“flow”,“flight”]输出&#xff1a;“fl” 示例 2&#xff1a; 输入&#xff1a;strs [“…

C++面试的一些总结day1:指针和引用的区别

文章目录 指针和引用的区别和作用定义区别作用 指针和引用的区别和作用 定义 指针&#xff1a;指针是一个变量&#xff0c;其值为指向对象的内存地址&#xff0c;而不是值本身。引用&#xff1a;可以理解为对象的别名&#xff0c;是另外一个变量的直接别名&#xff0c;用于创…

Spring不再支持Java8了

在今天新建模块的时候发现了没有java8的选项了&#xff0c;结果一查发现在11月24日&#xff0c;Spring不再支持8了&#xff0c;这可怎么办呢&#xff1f;我们可以设置来源为阿里云https://start.aliyun.com/ 。 java8没了 设置URL为阿里云的地址