当前位置: 首页 > news >正文

Spring AOP技术

1.AOP基本介绍

AOP 的全称 (aspect oriented programming) ,面向切面编程。
1.和传统的面向对象不同。 面向切面编程是根据自我的需求,将切面类的方法切入到其他的类的方法中。(这么说抽象吧!来张图来解释。)
如图

传统的面向对象方法是 对象.方法()然后被调用

面向切面编程是什么呢? 

首先满足 @1 类的这个方法是通过动态代理实现的比如有个A.say()方法。

                 然后有一个切面类B,这个类也有许多方法比如study(),但是不同的是,这个类中的方法study(),可以插入到A.say()的方法前后进行。 当A.say()被调用的时候,切面类B的study()方法就会被自动调用。

                这就和传统的直接调用B.study()方法不同,切面类的方法是直接插入到另外一个动态代理类的方法的前后的。

AOP的核心概念


面向切面编程(AOP)是一种编程范式,它允许开发者将横切关注点(如日志记录、事务管理、安全性等)与业务逻辑分离,从而提高代码的模块化和可维护性。在Java中,AOP通常通过使用框架如Spring来实现。

介绍AOP的关键术语

切面(Aspect):切面是封装横切关注点的模块。它包含了一组通知(Advice)和切入点(Pointcut)。
连接点(Joinpoint):在程序执行过程中的特定点,如方法的调用或执行,异常的抛出等。
切点(Pointcut):切点是定义在哪些连接点上应用通知的规则。
通知(Advice):通知是在切点上执行的代码,它定义了在连接点上执行的逻辑,如前置、后置、环绕等。
解释AOP的几种通知类型

前置(Before):在方法执行前执行的通知。
后置(After):在方法执行后执行的通知,无论方法是否成功执行。
环绕(Around):在方法调用前后都可以执行的通知,可以控制方法的调用过程。
异常(Throws):在方法抛出异常后执行的通知。
最终(AfterReturning):在方法正常返回后执行的通知。

2.AOP的快速入门

在xml配置下:

    <context:annotation-config/><context:component-scan base-package="aspectj"/><!--启用基于注解方式的AOP功能--><aop:aspectj-autoproxy proxy-target-class="true"/>

【Spring进阶系列丨第十篇】基于注解的面向切面编程(AOP)详解_spring 切面 注解-CSDN博客

3.AOP的切入表达式

语法细节

注意第一个*是包含了任意的权限修饰符和返回值。

方法说明

 注意细节

1. 切入表达式也可以指向类的方法 , 这时切入表达式会对该类 / 对象生效
2. 切入表达式也可以指向接口的方法 , 这时切入表达式会对实现了接口的类 / 对象生效
3. 切入表达式也可以对没有实现接口的类,进行切入 (因为Spring的CGLIB)。

 4.JoinPoint连接点

作用:通过 JoinPoint 可以获取到调用方法的签名 signature
方法:

// 获取目标方法名

joinPoint.getSignature().getName(); 

// 获取目标方法所属类的简单类名
joinPoint.getSignature().getDeclaringType().getSimpleName(); 

// 获取目标方法所属类的类名
joinPoint.getSignature().getDeclaringTypeName();

// 获取目标方法声明类型(public、private、protected)
joinPoint.getSignature().getModifiers(); 

// 获取传入目标方法的参数,返回一个数组
Object[] args = joinPoint.getArgs(); 

// 获取被代理的对象
joinPoint.getTarget(); 

// 获取代理对象自己
joinPoint.getThis(); 

 在如下代码中要将beforeMethod()方法切入到aspectj包下的SmartDog类的getSum()下


@Before(value = "execution(public float aspectj.SmartDog.getSum(float, float))")
public void beforeMethod(JoinPoint joinPoint){
joinPoint.getSignature().getName(); // 获取目标方法名
joinPoint.getSignature().getDeclaringType().getSimpleName(); // 获取目标方法所属类的简单类名
joinPoint.getSignature().getDeclaringTypeName(); // 获取目标方法所属类的类名
joinPoint.getSignature().getModifiers(); // 获取目标方法声明类型(public、private、protected)
Object[] args = joinPoint.getArgs(); // 获取传入目标方法的参数,返回一个数组
joinPoint.getTarget(); // 获取被代理的对象
joinPoint.getThis(); // 获取代理对象自己
}

5.返回,异常,环绕通知返回结果

//返回通知@AfterReturning(value = "execution(public float aspectj.SmartDog.getSum(float, float))", returning = "res")public void showSuccessEndLog(JoinPoint joinPoint, Object res) {Signature signature = joinPoint.getSignature();System.out.println("SmartAnimalAspect-切面类showSuccessEndLog()-方法执行正常结束-日志-方法名-" + signature.getName() + " 返回的结果是=" + res);}//异常通知@AfterThrowing(value = "execution(public float aspectj.SmartDog.getSum(float, float))", throwing = "throwable")public void showExceptionLog(JoinPoint joinPoint, Throwable throwable) {Signature signature = joinPoint.getSignature();System.out.println("SmartAnimalAspect-切面类showExceptionLog()-方法执行异常-日志-方法名-" + signature.getName() + " 异常信息=" + throwable);}

6.切入点表达式重用

在这些切入方法里面,如果是作用于同一个方法,就会让切入表达式感到重复和冗余,于是为了统一管理切入点表达式,可以使用切入点表达式重用技术

package aspectj;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.Arrays;/*** @version 1.0* 这是一个切面类*/
@Aspect
@Component("smartAnimalAspect")
public class SmartAnimalAspect {//    切入表达式重用技术@Pointcut(value = "execution(public float aspectj.SmartDog.getSum(float, float))")public void mypointcut(){}//给SmartDog配置前置,返回,异常,最终通知//解读//1.@Before表示我们目标对象执行前要执行的哪个方法//2.value = "execution(public float aspectj.SmartDog.getSum(float, float))"// 是指定切入到哪个类的哪个方法 形式是:访问修饰符 返回类型 全类名.方法名(形参列表) execution是执行的意思//  JoinPoint joinPoint 在底层执行的时候,由Aspectj切面框架,会给该切入方法传入jointPoint对象//  通过该对象可以获得相关的信息。//前置通知@Before(value = "mypointcut()")public void showBeginLog(JoinPoint joinPoint) {//通过连接点对象joinPoint 可以获取方法签名Signature signature = joinPoint.getSignature();System.out.println("SmartAnimalAspect-切面类showBeginLog()[使用的myPointCut()]-方法执行前-日志-方法名-" + signature.getName() + "-参数 "+ Arrays.asList(joinPoint.getArgs()));}//返回通知@AfterReturning(value = "mypointcut()",returning = "res")public void showSuccessEndLog(JoinPoint joinPoint, Object res) {Signature signature = joinPoint.getSignature();System.out.println("SmartAnimalAspect-切面类showSuccessEndLog()-方法执行正常结束-日志-方法名-" + signature.getName() + " 返回的结果是=" + res);}//异常通知@AfterThrowing(value = "mypointcut()",throwing = "throwable")public void showExceptionLog(JoinPoint joinPoint, Throwable throwable) {Signature signature = joinPoint.getSignature();System.out.println("SmartAnimalAspect-切面类showExceptionLog()-方法执行异常-日志-方法名-" + signature.getName() + " 异常信息=" + throwable);}//最终通知@After(value = "mypointcut()")public void showFinallyEndLog(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("SmartAnimalAspect-切面类showFinallyEndLog()-方法最终执行完毕-日志-方法名-" + signature.getName());}}

 7.切面优先级问题

切面优先级问题 :
如果同一个方法,有多个切面在同一个切入点切入,那么执行的优先级如何控制 .
基本语法
@order(value=n) 来控制 n 值越小,优先级越高 .

举例
切面类1(优先执行)

package aspectj;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Arrays;/*** @version 1.0* 这是一个切面类*/
@Order(value = 1)
@Aspect
@Component("smartAnimalAspect")
public class SmartAnimalAspect {//    切入表达式重用技术@Pointcut(value = "execution(public float aspectj.SmartDog.getSum(float, float))")public void mypointcut(){}//前置通知
//    @Before(value = "execution(public float aspectj.SmartDog.getSum(float, float))")@Before(value = "mypointcut()")public void showBeginLog(JoinPoint joinPoint) {//通过连接点对象joinPoint 可以获取方法签名Signature signature = joinPoint.getSignature();System.out.println("1前置通知" + signature.getName() + "-参数 "+ Arrays.asList(joinPoint.getArgs()));}//返回通知
//    @AfterReturning(value = "execution(public float aspectj.SmartDog.getSum(float, float))", returning = "res")@AfterReturning(value = "mypointcut()",returning = "res")public void showSuccessEndLog(JoinPoint joinPoint, Object res) {Signature signature = joinPoint.getSignature();System.out.println("1返回通知" + signature.getName() + " 返回的结果是=" + res);}//异常通知
//    @AfterThrowing(value = "execution(public float aspectj.SmartDog.getSum(float, float))", throwing = "throwable")@AfterThrowing(value = "mypointcut()",throwing = "throwable")public void showExceptionLog(JoinPoint joinPoint, Throwable throwable) {Signature signature = joinPoint.getSignature();System.out.println("1异常通知" + signature.getName() + " 异常信息=" + throwable);}//最终通知
//    @After(value = "execution(public float aspectj.SmartDog.getSum(float, float))")@After(value = "mypointcut()")public void showFinallyEndLog(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("1最终通知" + signature.getName());}}

切面类2(没有切面类1的优先级高)

package aspectj;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;import java.util.Arrays;/*** @version 1.0* 这是一个切面类*/
@Order(value = 2)
@Aspect
@Component("smartAnimalAspect2")
public class SmartAnimalAspect2 {//    切入表达式重用技术@Pointcut(value = "execution(public float aspectj.SmartDog.getSum(float, float))")public void mypointcut(){}//前置通知
//    @Before(value = "execution(public float aspectj.SmartDog.getSum(float, float))")@Before(value = "mypointcut()")public void showBeginLog(JoinPoint joinPoint) {//通过连接点对象joinPoint 可以获取方法签名Signature signature = joinPoint.getSignature();System.out.println("2前置通知");}//返回通知
//    @AfterReturning(value = "execution(public float aspectj.SmartDog.getSum(float, float))", returning = "res")@AfterReturning(value = "mypointcut()",returning = "res")public void showSuccessEndLog(JoinPoint joinPoint, Object res) {Signature signature = joinPoint.getSignature();System.out.println( "2返回通知 返回的结果是=" + res);}//异常通知
//    @AfterThrowing(value = "execution(public float aspectj.SmartDog.getSum(float, float))", throwing = "throwable")@AfterThrowing(value = "mypointcut()",throwing = "throwable")public void showExceptionLog(JoinPoint joinPoint, Throwable throwable) {Signature signature = joinPoint.getSignature();System.out.println("2异常通知" + throwable);}//最终通知
//    @After(value = "execution(public float aspectj.SmartDog.getSum(float, float))")@After(value = "mypointcut()")public void showFinallyEndLog(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("2最终通知" + signature.getName());}}

结果: 

 

注意 

不能理解成:优先级高的每个消息通知都先执行,这个和方法调用机制(和 Filter 过滤器
链式调用类似)

8.基于XML的AOP

定义SmartAnimalable接口

package xml;/*** @author ygd*/
public interface SmartAnimalable {float getSum(float i, float j);float getSub(float i, float j);
}

定义SmartDog类

package xml;/*** @author ygd*/
public class SmartDog implements SmartAnimalable {@Overridepublic float getSum(float i, float j) {float result = i + j;System.out.println("getSum() 方法内部打印 result= " + result);return result;}@Overridepublic float getSub(float i, float j) {float result = i - j;System.out.println("getSub() 方法内部打印 result= " + result);return result;}
}

定义SmartAnimalAspect切面类

package xml;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;import java.util.Arrays;/*** @version 1.0* 这是一个基于XML的切面类*/public class SmartAnimalAspect {public void showBeginLog(JoinPoint joinPoint) {//通过连接点对象joinPoint 可以获取方法签名Signature signature = joinPoint.getSignature();System.out.println("1前置通知" + signature.getName() + "-参数 "+ Arrays.asList(joinPoint.getArgs()));}public void showSuccessEndLog(JoinPoint joinPoint, Object res) {Signature signature = joinPoint.getSignature();System.out.println("1返回通知" + signature.getName() + " 返回的结果是=" + res);}public void showExceptionLog(JoinPoint joinPoint, Throwable throwable) {Signature signature = joinPoint.getSignature();System.out.println("1异常通知" + signature.getName() + " 异常信息=" + throwable);}public void showFinallyEndLog(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("1最终通知" + signature.getName());}}

定义beans01.xml

 

<?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: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/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"><!--配置一个切面类对象-bean--><bean class="xml.SmartAnimalAspect" id="smartAnimalAspect"/>
<!--配置SmartDog对象-bean--><bean class="xml.SmartDog" id="dog"/>
<!--配置切面类,一定要引入xmlns:aop命名空间--><aop:config>
<!-- 注意顺序,先配置切入点,在配置切面对象-->
<!--配置切入点--><aop:pointcut id="mypointcut" expression="execution(public float xml.SmartDog.getSum(float, float))"/>
<!--这里指定切面对象--><aop:aspect ref="smartAnimalAspect" order="10">
<!--配置前置通知--><aop:before method="showBeginLog" pointcut-ref="mypointcut"/>
<!--配置返回通知--><aop:after-returning method="showSuccessEndLog" pointcut-ref="mypointcut" returning="res"/>
<!--配置异常通知--><aop:after-throwing method="showExceptionLog" pointcut-ref="mypointcut" throwing="throwable"/>
<!--配置最终通知--><aop:after method="showFinallyEndLog" pointcut-ref="mypointcut"/></aop:aspect></aop:config></beans>

注意点:要 先配置切面点,在配置切面类

xml的语法,跟上面所写的基于注解的aop道理都是一样的。

9.Spring的AOP机制是基于Spring框架中的基于JDK的动态代理和基于CGLib的动态代理

动态代理 基于jdk的Proxy(面向接口) 与spring的CGlib(面向父类)-CSDN博客

相关文章:

Spring AOP技术

1.AOP基本介绍 AOP 的全称 (aspect oriented programming) &#xff0c;面向切面编程。 1.和传统的面向对象不同。 面向切面编程是根据自我的需求&#xff0c;将切面类的方法切入到其他的类的方法中。&#xff08;这么说抽象吧&#xff01;来张图来解释。&#xff09; 如图 传…...

数字IC实践项目(10)—基于System Verilog的DDR4 Model/Tb 及基础Verification IP的设计与验证(付费项目)

数字IC实践项目&#xff08;10&#xff09;—基于System Verilog的DDR4 Model/Tb 及基础Verification IP的设计与验证&#xff08;付费项目&#xff09; 前言项目框图1&#xff09;DDR4 Verification IP2&#xff09;DDR4 JEDEC Model & Tb 项目文件1&#xff09;DDR4 Veri…...

MATLAB保存多帧图形为视频格式

基本思路 在Matlab中&#xff0c;要将drawnow绘制的多帧数据保存为视频格式&#xff0c;首先需要创建一个视频写入对象。这个对象用于将每一帧图像数据按照视频格式的要求进行组合和编码。然后&#xff0c;在每次drawnow更新绘图后&#xff0c;将当前的图形窗口内容捕获为一帧图…...

redis7.x源码分析:(3) dict字典

dict字典采用经典hash表数据结构实现&#xff0c;由键值对组成&#xff0c;类似于C中的unordered_map。两者在代码实现层面存在一些差异&#xff0c;比如gnustl的unordered_map分配的桶数组个数是&#xff08;质数n&#xff09;&#xff0c;而dict分配的桶数组个数是&#xff0…...

连续九届EI稳定|江苏科技大学主办

【九届EI检索稳定|江苏科技大学主办 | IEEE出版 】 &#x1f388;【截稿倒计时】&#xff01;&#xff01;&#xff01; ✨徐秘书&#xff1a;gsra_huang ✨往届均已检索&#xff0c;已上线IEEE官网 &#x1f38a;第九届清洁能源与发电技术国际学术会议&#xff08;CEPGT 2…...

HarmonyOS NEXT应用开发实战 ( 应用的签名、打包上架,各种证书详解)

前言 没经历过的童鞋&#xff0c;首次对HarmonyOS的应用签名打包上架可能感觉繁琐。需要各种秘钥证书生成和申请&#xff0c;混在一起也分不清。其实搞清楚后也就那会事&#xff0c;各个文件都有它存在的作用。 HarmonyOS通过数字证书与Profile文件等签名信息来保证鸿蒙应用/…...

【CICD】CICD 持续集成与持续交付在测试中的应用

一、什么是CICD&#xff1f; CI/CD 是指持续集成&#xff08;Continuous Integration&#xff09;和持续部署&#xff08;Continuous Deployment&#xff09;或持续交付&#xff08;Continuous Delivery&#xff09; 1.1 持续集成&#xff08;Continuous Integration&#xf…...

Dolby TrueHD和Dolby Digital Plus (E-AC-3)编码介绍

文章目录 1. Dolby TrueHD特点总结 2. Dolby Digital Plus (E-AC-3)特点总结 Dolby TrueHD 与 Dolby Digital Plus (E-AC-3) 的对比 Dolby TrueHD和Dolby Digital Plus (E-AC-3) 是两种高级的杜比音频编码格式&#xff0c;常用于蓝光影碟、流媒体、影院等高品质音频传输场景。它…...

数字频率计的设计-- 基于 HDL 方法

目录 数字频率计的设计 1.计数、锁存与显示译码电路设计 2.主控电路设计 3.分频电路设计 4.顶层电路设计 伪随机序列发生器 的设计 数字频率计的设计 基于HDL设计数字系统时&#xff0c;可以根据需要应用Verilog HDL描述所需要的功能电路&#xff0c;既有利于节约资源&am…...

[程序员] 没有产生core文件的原因

最近和同事一块看一个core文件没有产生的问题,总结了一些在CSDN的专栏里。分析的过程,参考使用了ftrace的功能,感觉非常实用。 如果有需要可以参考。大体上就这么几种情况:信号的特殊处理,coredump相关的配置没有设置正确,文件系统访问权限问题,setuid相关的不匹配问题。…...

【数字图像处理+MATLAB】基于 Sobel 算子计算图像梯度并进行边缘增强:使用 imgradientxy 函数

引言 在图像处理中&#xff0c;边缘通常是图像中像素强度变化最大的地方&#xff0c;这种变化可以通过计算图像的梯度来量化。梯度是一个向量&#xff0c;它的方向指向像素强度增加最快的方向&#xff0c;它的大小&#xff08;或者说幅度&#xff09;表示像素强度增加的速度。…...

P10901 [蓝桥杯 2024 省 C] 封闭图形个数

铁子们好呀&#xff0c;今天博主给大家更新一道编程题&#xff01;&#xff01;&#xff01; 题目链接如下&#xff1a; P10901 [蓝桥杯 2024 省 C] 封闭图形个数 好&#xff0c;接下来&#xff0c;我将从三个方面讲解这道例题。分别是 题目解析算法原理代码实现 文章目录 1.题…...

ubuntu-desktop-24.04上手指南(更新阿里源、安装ssh、安装chrome、设置固定IP、安装搜狗输入法)

ubuntu-desktop-24.04上手指南(更新阿里源、安装ssh、安装chrome、设置固定IP、安装搜狗输入法) 一、更新并安装基础软件 #切换root用户 sudo su -#更新 apt update #升级 apt upgrade#install vim apt install vim#install net-tools apt install net-tools二、安装ssh并设置…...

手机直连卫星NTN通信初步研究

目录 1、手机直连卫星之序幕 2、卫星NTN及其网络架构 2.1 NTN 2.2 NTN网络架构 3、NTN的3GPP标准化进程 3.1 NTN需要适应的特性 3.2 NTN频段 3.3 NTN的3GPP标准化进程概况 3.4 NTN的3GPP标准化进程的详情 3.4.1 NR-NTN 3.4.1.1 NTN 的无线相关 SI/WI 3.4.1.2…...

蓝桥杯c++算法学习【2】之搜索与查找(九宫格、穿越雷区、迷宫与陷阱、扫地机器人:::非常典型的必刷例题!!!)

别忘了请点个赞收藏关注支持一下博主喵&#xff01;&#xff01;&#xff01; 关注博主&#xff0c;更多蓝桥杯nice题目静待更新:) 搜索与查找 一、九宫格 【问题描述】 小明最近在教邻居家的小朋友小学奥数&#xff0c;而最近正好讲述到了三阶幻方这个部分&#xff0c;三 …...

Android加载pdf

依赖 implementation com.squareup.okhttp3:okhttp:4.9.1 implementation com.github.barteksc:android-pdf-viewer:3.2.0-beta.1在project.build中添加该源 maven { url "https://repository.liferay.com/nexus/content/repositories/public/" }XML <LinearLa…...

IOT物联网低代码可视化大屏解决方案汇总

目录 参考来源云服务商阿里云物联网平台产品主页产品文档 开源项目DGIOT | 轻量级工业物联网开源平台项目特点项目地址开源许可 IoTGateway | 基于.NET6的跨平台工业物联网网关项目特点项目地址开源许可 IoTSharp | 基于.Net Core开源的物联网基础平台项目特点项目地址开源许可…...

Python的面向对象day7

1、什么是面向对象 面向对象称为OO&#xff0c;他通过将数据和功能封装在一个被称为‘对象’的实体中&#xff0c;来组织和管理代码。面向对象变成&#xff08;OOP&#xff09;具有四个特性&#xff0c;封装、继承、多态、抽象 优点&#xff1a;模块化、安全性高、代码重用性…...

计算机网络(11)和流量控制补充

这一篇对数据链路层中的和流量控制进行详细学习 流量控制&#xff08;Flow Control&#xff09;是计算机网络中确保数据流平稳传输的技术&#xff0c;旨在防止数据发送方发送过多数据&#xff0c;导致接收方的缓冲区溢出&#xff0c;进而造成数据丢失或传输失败。流量控制通常…...

Rust 所有权机制

Rust 所有权机制 本文示例代码地址 所有权是Rust中最独特的特性&#xff0c;它让Rust无需GC就可以保证内存安全。 什么是所有权&#xff1f; 所有权&#xff08;ownership&#xff09;是 Rust 用于如何管理内存的一组规则。所有程序都必须管理其运行时使用计算机内存的方式…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...