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

详解Spring AOP(一)

目录

1. AOP概述

2.Spring AOP快速入门

2.1引入AOP依赖

2.2编写AOP程序

 3.Spring AOP核心概念

3.1切点(PointCut)

3.2连接点(Join Point)

3.3通知(Advice)

3.4切面(Aspect)

4.通知类型

 5.@PointCut

 6.切面优先级 @Order


1. AOP概述

AOP(Aspect Oriented Programming,面向切面编程)是一种编程范式,它旨在通过预编译方式和运行期间动态代理实现程序功能的统一维护。

AOP定义

  1. AOP是OOP(面向对象编程)的延续,是软件开发中的一个热点技术。
  2. 它是Spring框架中的一个重要内容,也是函数式编程的一种衍生范型。
  3. AOP通过“切面”对业务逻辑的各个部分进行隔离,降低业务逻辑之间的耦合度,提高程序的可重用性和开发效率。

 与OOP的区别:

OOP针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分。

AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。

应用场景:记录日志、性能监控、权限控制、缓存优化、事务管理(如声明式事务)

案例分析:

我们现在有⼀个项⽬ , 项⽬中开发了很多的业务功能

现在有⼀些业务的执行效率比较低, 耗时较长, 我们需要对接口进行优化.

第⼀步就需要定位出执行耗时比较长的业务方法, 再针对该业务方法来进行优化

何定位呢? 我们就需要统计当前项目中每⼀个业务方法的执行耗时.

如何统计呢? 可以在业务方法运行前和运行后, 记录下方法的开始时间和结束时间, 两者之差就是这个方法的耗时.

这种方法是可以解决问题的, 但⼀个项⽬中会包含很多业务模块, 每个业务模块又有很多接口 , ⼀个接口又包含很多方法, 如果我们要在每个业务方法中都记录方法的耗时, 会增加特别多的工作.

AOP就可以做到在不改动这些原始方法的基础上, 针对特定的方法进⾏功能的增强.

AOP的作用:在程序运行期间在不修改源代码的基础对已有方法进行增强(无侵⼊性: 解耦)

2.Spring AOP快速入门

需求:统计系统各个方法的zhixing

2.1引入AOP依赖

pom.xml文件中添加配置

 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>

2.2编写AOP程序

记录Controller中每个方法的执行时间

 @Slf4j@Aspect@Componentpublic class TimeAspect {/*** 记录⽅法耗时 */@Around("execution(* com.example.demo.controller.*.*(..))")public Object recordTime(ProceedingJoinPoint pjp) throws Throwable { //记录⽅法执⾏开始时间long begin = System.currentTimeMillis(); //执⾏原始⽅法Object result = pjp.proceed(); //记录⽅法执⾏结束时间long end = System.currentTimeMillis(); //记录⽅法执⾏耗时log.info(pjp.getSignature() + "执⾏耗时 : {}ms", end - begin);return result;}}

运行程序, 观察日志

 对代码进行简单分析:

1.@Aspect:标识这是一个切面类
2.@Around:环绕通知,在目标方法的前后都会被执行.后面的表达式表示对哪些方法进行增强
3.ProceedingJoinPoint.proceed()让原始方法执行

整个代码划分为三部分 

我们通过AOP入门程序完成了业务接口执行耗时的统计.

通过上面的程序,我们也可以感受到AOP面向切面编程的一些优势:

  • 代码无侵入:不修改原始的业务方法,就可以对其进行了功能的增强或者是功能的改变
  • 减少了重复代码
  • 提高开发效率
  • 维护方便

 3.Spring AOP核心概念

3.1切点(PointCut)

切点(Pointcut),也称之为"切入点"
切点的作用就是提供一组规则(使用AspectJ pointcut expression language来描述),告诉程序对哪些方法来进行功能增强.

上面的表达式execution(* com.example.demo.controller.*.*(..))就是切点表达式. 

3.2连接点(Join Point)

满足切点表达式规则的方法,就是连接点.也就是可以被AOP控制的方法以入门程序举例,所有com.example.demo.controller路径下的方法,都是连接点.

 package com.example.demo.controller; @RequestMapping("/book") @RestControllerpublic class BookController { @RequestMapping("/addBook")public Result addBook(BookInfo bookInfo) {//...代码省略} @RequestMapping("/queryBookById")public BookInfo queryBookById(Integer bookId){//...代码省略} @RequestMapping("/updateBook")public Result updateBook(BookInfo bookInfo) {//...代码省略}}

上述BookController中的方法都是连接点

切点和连接点的关系

连接点是满足切点表达式的元素.切点可以看做是保存了众多连接点的一个集合

比如:

切点表达式:学校全体教师

连接点就是:张三,李四等各个老师

3.3通知(Advice)

通知就是具体要做的工作,指哪些重复的逻辑,也就是共性功能(最终体现为一个方法)比如上述程序中记录业务方法的耗时时间,就是通知.

在AOP面向切面编程当中,我们把这部分重复的代码逻辑抽取出来单独定义,这部分代码就是通知的内容.

3.4切面(Aspect)

切面(Aspect)=切点(Pointcut)+通知(Advice)

通过切面就能够描述当前AOP程序需要针对于哪些方法,在什么时候执行什么样的操作.

切面既包含了通知逻辑的定义,也包括了连接点的定义.

 切面所在的类,我们一般称为切面类(被@Aspect注解标识的类)

4.通知类型

上面我们讲了什么是通知,接下来学习通知的类型.

Spring中AOP的通知类型有以下几种:

@Around:环绕通知,此注解标注的通知方法在目标方法前,后都被执行
@Before:前置通知,此注解标注的通知方法在目标方法前被执行
@After:后置通知,此注解标注的通知方法在目标方法后被执行,无论是否有异常都会执行
@AfterReturning:返回后通知,此注解标注的通知方法在目标方法后被执行,有异常不执行
@AfterThrowing:异常后通知,此注解标注的通知方法发生异常后执行

 通过代码来测试这几个通知:

import lombok.extern.slf4j.Slf4j;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Component;@Slf4j@Aspect@Componentpublic class AspectDemo { //前置通知@Before("execution(* com.example.demo.controller.*.*(..))")public void doBefore() {log.info("执⾏  Before ⽅法");} //后置通知@After("execution(* com.example.demo.controller.*.*(..))")public void doAfter() {log.info("执⾏  After ⽅法");} //返回后通知@AfterReturning("execution(* com.example.demo.controller.*.*(..))")public void doAfterReturning() {log.info("执⾏  AfterReturning ⽅法");} //抛出异常后通知@AfterThrowing("execution(* com.example.demo.controller.*.*(..))")public void doAfterThrowing() {log.info("执⾏  doAfterThrowing ⽅法");} //添加环绕通知@Around("execution(* com.example.demo.controller.*.*(..))")public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {log.info("Around ⽅法开始执⾏");Object result = joinPoint.proceed();log.info("Around ⽅法结束执⾏");return result;}}

编写测试程序:

 package com.example.demo.controller; import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RequestMapping("/test") @RestControllerpublic class TestController { @RequestMapping("/t1")public String t1() {return "t1";} @RequestMapping("/t2")public boolean t2() {int a = 10 / 0;return true;}}

运行程序,观察日志:
1.正常运行的情况

http://127.0.0.1:8080/test/t1

观察日志

程序正常运行的情况下,@AfterThrowing标识的通知方法不会执行
从上图可以看出,@Around标识的通知方法包含两部分,一个"前置逻辑",一个"后置逻辑",其中"前置逻辑"会先于@Before标识的通知方法执行,"后置逻辑"会晚于@After标识的通知方法执行

2.异常时的情况

http://127.0.0.1:8080/test/t2

观察日志: 

程序发生异常的情况下:
@AfterReturning标识的通知方法不会执行@AfterThrowing标识的通知方法执行了
@Around环绕通知中原始方法调用时有异常,通知中的环绕后的代码逻辑也不会在执行

注意事项:
@Around环绕通知需要调用ProceedingJoinPoint.proceed()来让原始方法执行,其他通知不需要考虑目标方法执行.
@Around环绕通知方法的返回值,必须指定为Object来接收原始方法的返回值,否则原始方法执行完毕,是获取不到返回值的.
一个切面类可以有多个切点.

 5.@PointCut


上面代码存在一个问题,就是存在大量重复的切点表达式execution(* com.example.demo.controller.*.*(..)),

Spring提供@PointCut注解,把公共的切点表达式提取出来,需要用到时引用该切入点表达式即可.
上述代码就可以修改为:

 @Slf4j@Aspect@Componentpublic class AspectDemo {//定义切点(公共的切点表达式)@Pointcut("execution(* com.example.demo.controller.*.*(..))")private void pt(){}//前置通知@Before("pt()")public void doBefore() {//...代码省略} //后置通知@After("pt()")public void doAfter() {//...代码省略} //返回后通知@AfterReturning("pt()")public void doAfterReturning() {//...代码省略} //抛出异常后通知@AfterThrowing("pt()")public void doAfterThrowing() {//...代码省略} //添加环绕通知     @Around("pt()")public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {//...代码省略}}

注意:

当切点定义使用private修饰时,仅能在当前切面类中使用,当其他切面类也要使用当前切点定义时,就需要把private改为public.

引用方式为:全限定类名.方法名()

 @Slf4j@Aspect@Componentpublic class AspectDemo2 { //前置通知@Before("com.example.demo.aspect.AspectDemo.pt()")public void doBefore() {log.info("执⾏  AspectDemo2 -> Before ⽅法");}}

 6.切面优先级 @Order

当我们在一个项目中,定义了多个切面类并且这些切面类的多个切入点都匹配到了同一个目标方法

当目标方法运行的时候,这些切面类中的通知方法都会执行,那么这几个通知方法的执行顺序是什么样的呢?
我们还是通过程序来求证:

定义多个切面类:

为简单化,只写@Before和aAfter两个通知:

 @Componentpublic class AspectDemo1 {@Pointcut("execution(* com.example.demo.controller.*.*(..))")private void pt(){}//前置通知@Before("pt()")public void doBefore() {log.info("执⾏  AspectDemo1 -> Before ⽅法");} //后置通知@After("pt()")public void doAfter() {log.info("执⾏  AspectDemo1 -> After ⽅法");}}
 @Componentpublic class AspectDemo2 {@Pointcut("execution(* com.example.demo.controller.*.*(..))")private void pt(){}//前置通知@Before("pt()")public void doBefore() {log.info("执⾏  AspectDemo2 -> Before ⽅法");} //后置通知@After("pt()")public void doAfter() {log.info("执⾏  AspectDemo2 -> After ⽅法");}}
 @Componentpublic class AspectDemo3 {@Pointcut("execution(* com.example.demo.controller.*.*(..))")private void pt(){}//前置通知@Before("pt()")public void doBefore() {log.info("执⾏  AspectDemo3 -> Before ⽅法");} //后置通知@After("pt()")public void doAfter() {log.info("执⾏  AspectDemo3 -> After ⽅法");}}

运行程序,访问接口:

http://127.0.0.1:8080/test/t1

观察日志:
 

通过上述程序的运行结果,可以看出:
存在多个切面类时,默认按照切面类的类名字母排序:
@Before通知:字母排名靠前的先执行
@After通知:字母排名靠前的后执行
但这种方式不方便管理,我们的类名更多还是具备一定含义的.
Spring给我们提供了一个新的注解来控制这些切面通知的执行顺序:@Order

使用方式如下:
 

 @Aspect@Component@Order(2)public class AspectDemo1 {//...代码省略 }@Aspect@Component@Order(1)public class AspectDemo2 {//...代码省略 }@Aspect@Component@Order(3)public class AspectDemo3 {//...代码省略 }

重新运行程序,访问接口:

http://127.0.0.1:8080/test/t1

观察日志:

通过上述程序的运行结果,得出结论:
@Order注解标识的切面类,执行顺序如下:
@Before通知:数字越小先执行
@After通知:数字越大先执行
@Order控制切面的优先级,先执行优先级较高的切面,再执行优先级较低的切面,最终执行目标方法。

相关文章:

详解Spring AOP(一)

目录 1. AOP概述 2.Spring AOP快速入门 2.1引入AOP依赖 2.2编写AOP程序 3.Spring AOP核心概念 3.1切点&#xff08;PointCut&#xff09; 3.2连接点&#xff08;Join Point&#xff09; 3.3通知&#xff08;Advice&#xff09; 3.4切面&#xff08;Aspect&#xff09; …...

读者写者问题(读者优先、公平竞争、写者优先)

1.读者优先 当有读者进程进行读时&#xff0c;允许多个读者同时读&#xff0c;但不允许写者写&#xff1b;当有写者进程进行写时&#xff0c;不允许其他写者写&#xff0c;也不允许读者读 读者算法&#xff1a; p(r_mutex); //申请修改read_count if read_count0:p(mutex); …...

Springboot开发之 Excel 处理工具(二)-- Easyexcel

一、Easyexcel 简介 EasyExcel是一个基于Java的Excel处理工具库&#xff0c;它的核心设计理念是快速、简洁&#xff0c;并且能够有效解决处理大文件时的内存溢出问题。使用EasyExcel&#xff0c;开发者可以在几乎不需要考虑性能和内存消耗的情况下&#xff0c;轻松实现Excel文…...

6月27日云技术研讨会 | 中央集中架构新车型功能和网络测试解决方案

会议摘要 “软件定义汽车”新时代下&#xff0c;整车电气电气架构向中央-区域集中式发展已成为行业共识&#xff0c;车型架构的变革带来更复杂的整车功能定义、更多的新技术的应用&#xff08;如SOA服务化、TSN等&#xff09;和更短的车型研发周期&#xff0c;对整车和新产品研…...

微信小程序生命周期

微信小程序的生命周期包括两个主要部分&#xff1a;应用生命周期和页面生命周期。下面我将详细介绍它们的具体内容。 应用生命周期 onLaunch&#xff1a; 触发时机&#xff1a;小程序初始化完成时&#xff08;全局只触发一次&#xff09;。 用途&#xff1a;通常用于进行一些…...

【JS重点15】原型对象概述

目录 一&#xff1a;构造函数缺陷 二&#xff1a;原型 1 原型是是什么 2 原型对象的作用 3 原型对象this指向问题 4 利用原型对象添加方法 给JS内置构造函数Array添加最大值方法 给JS内置构造函数Array添加求和方法 三&#xff1a;Constructor属性 四&#xff1a;如何…...

Java之Hutool/Guava/Apache Commons工具包项目实践

概述 Hutool是一个Java工具包,提供了丰富的工具类和方法,目的是简化开发任务提高开发效率;适用于需要快速开发和实现多种功能的场景,适合项目需要处理字符串、日期、文件等常见任务时~ toBeBetterJavaer/docs/common-tool/StringUtils.md at master itwanger/toBeBetterJavae…...

哈喽GPT-4o——对GPT-4o 提示词的思考与看法

目录 一、提示词二、常用的提示词案例1、写作助理2、改写为小红书风格3、英语翻译和改写4、论文式回答5、主题解构6、提问助手7、Nature风格润色8、结构总结9、编程助手10、充当终端/解释器 大家好&#xff0c;我是哪吒。 最近&#xff0c;ChatGPT在网络上广受欢迎&#xff0c…...

《计算机英语》 Unit 3 Software Engineering 软件工程

Section A Software Engineering Methodologies 软件工程方法论 Software development is an engineering process. 软件开发是一个工程过程。 The goal of researchers in software engineering is to find principles that guide the software development process and lea…...

2024-6-18(沉默Spring,Springboot)

1.Spring小结 我们最后再来体会一下用 Spring 创建对象的过程&#xff1a; 通过 ApplicationContext 这个 IoC 容器的入口&#xff0c;用它的两个具体的实现子类&#xff0c;从 class path 或者 file path 中读取数据&#xff0c;用 getBean() 获取具体的 bean instance。 那…...

Java热部署:让应用更新如丝般顺滑,告别繁琐重启!

目录 手动启动热部署 自动启动热部署 参与热部署监控的文件范围配置 关闭热部署 什么是热部署&#xff1f;简单说就是你程序改了&#xff0c;现在要重新启动服务器&#xff0c;嫌麻烦&#xff1f;不用重启&#xff0c;服务器会自己悄悄的把更新后的程序给重新加载一遍&…...

微信小程序毕业设计-小区疫情防控系统项目开发实战(附源码+论文)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计…...

PyTorch -- RNN 快速实践

RNN Layer torch.nn.RNN(input_size,hidden_size,num_layers,batch_first) input_size: 输入的编码维度hidden_size: 隐含层的维数num_layers: 隐含层的层数batch_first: True 指定输入的参数顺序为&#xff1a; x&#xff1a;[batch, seq_len, input_size]h0&#xff1a;[batc…...

SpringBoot 快速入门(保姆级详细教程)

目录 一、Springboot简介 二、SpringBoot 优点&#xff1a; 三、快速入门 1、新建工程 方式2&#xff1a;使用Spring Initializr创建项目 写在前面&#xff1a; SpringBoot 是 Spring家族中的一个全新框架&#xff0c;用来简化spring程序的创建和开发过程。SpringBoot化繁…...

【第18章】Vue实战篇之登录界面

文章目录 前言一、数据绑定1. 数据绑定2. 数据清空 二、表单校验1. 代码2. 展示 三、登录1.登录按钮2.user.js3. login 四、展示总结 前言 上一章完成用户注册&#xff0c;这一章主要做用户登录。 一、数据绑定 登录和注册使用相同的数据绑定 1. 数据绑定 <!-- 登录表单 -…...

[C++]使用C++部署yolov10目标检测的tensorrt模型支持图片视频推理windows测试通过

【测试通过环境】 vs2019 cmake3.24.3 cuda11.7.1cudnn8.8.0 tensorrt8.6.1.6 opencv4.8.0 【部署步骤】 获取pt模型&#xff1a;https://github.com/THU-MIG/yolov10训练自己的模型或者直接使用yolov10官方预训练模型 下载源码&#xff1a;https://github.com/laugh12321/yol…...

分享uniapp + Springboot3+vue3小程序项目实战

分享uniapp Springboot3vue3小程序项目实战 经过10天敲代码&#xff0c;终于从零到项目测试完成&#xff0c;一个前后端分离的小程序实战项目学习完毕 时间从6月12日 到6月22日&#xff0c;具有程序开发基础&#xff0c;第一次写uniapp,Springboot以前用过&#xff0c;VUE3也…...

Ubuntu 24.04安装zabbix7.0.0图形中文乱码

当zabbix安装完成后&#xff0c;设置中文界面时&#xff0c;打开图形&#xff0c;中文内容会显示方框乱码&#xff0c;是因为服务器字体中没有相关的中文字体&#xff0c;需要更换。 1、找到中文字体&#xff0c;可以在网络上下载《得意黑》开源字体&#xff0c;也可以在windo…...

MybatisPlus 调用 原生SQL

方式一 DemoMapper.java Mapper public interface DemoMapper extends BaseMapper<TableConfig> {Update("${sql}")int createTable(Param("sql") String sql); }测试代码 SpringBootTest class DemoMapperTest {Resourceprivate DemoMapper demo…...

1.SG90

目录 一.实物图 二.原理图 三.简介 四.工作原理 一.实物图 二.原理图 三.简介 舵机&#xff08;英文叫Servo&#xff09;&#xff0c;是伺服电机的一种&#xff0c;伺服电机就是带有反馈环节的电机&#xff0c;这种电机可以进行精确的位置控制或者输出较高的扭矩。舵机…...

【yolov8语义分割】跑通:下载yolov8+预测图片+预测视频

1、下载yolov8到autodl上 git clone https://github.com/ultralytics/ultralytics 下载到Yolov8文件夹下面 另外&#xff1a;现在yolov8支持像包一样导入&#xff0c;pip install就可以 2、yolov8 语义分割文档 看官方文档&#xff1a;主页 -Ultralytics YOLO 文档 还能切…...

基于STM8系列单片机驱动74HC595驱动两个3位一体的数码管

1&#xff09;单片机/ARM硬件设计小知识&#xff0c;分享给将要学习或者正在学习单片机/ARM开发的同学。 2&#xff09;内容属于原创&#xff0c;若转载&#xff0c;请说明出处。 3&#xff09;提供相关问题有偿答疑和支持。 为了节省单片机MCU的IO口资源驱动6个数码管&…...

Jlink下载固件到RAM区

Jlink下载固件到RAM区 准备批处理搜索exe批处理读取bin数据解析调用jlink批处理准备jlink脚本 调用执行 环境&#xff1a;J-Flash V7.96g 平台&#xff1a;arm cortex-m3 准备批处理 搜索exe批处理 find_file.bat echo off:: 自动识别脚本名和路径 set "SCRIPT_DIR%~dp…...

Kotlin基础——Typeclass

高阶类型 如在Iterable新增泛型方法时 interface Iterable<T> {fun filter(p: (T) -> Boolean): Iterable<T>fun remove(p: (T) -> Boolean): Iterable<T> filter { x -> !p(x) } }对应的List、Set实现上述方法时仍需要返回具体的类型 interfac…...

DC-DC 高压降压、非隔离AC-DC、提供强大的动力,选择优质电源芯片-(昱灿)

畅享长续航&#xff0c;尽在我们的充电芯片&#xff01; 无论是手机、平板还是智能设备&#xff0c;长时间使用后电量不足总是令人头疼。然而&#xff0c;我们的充电芯片将为您带来全新的充电体验&#xff01;采用先进的技术&#xff0c;我们的充电芯片能够提供快速而稳定的充电…...

GPT-4o的视觉识别能力,将绕过所有登陆的图形验证码

知识星球&#x1f517;除了包含技术干货&#xff1a;《Java代码审计》《Web安全》《应急响应》《护网资料库》《网安面试指南》还包含了安全中常见的售前护网案例、售前方案、ppt等&#xff0c;同时也有面向学生的网络安全面试、护网面试等。 我们来看一下市面上常见的图形验证…...

【LinuxC语言】进程间的通信——管道

文章目录 前言不同进程间通信的方式管道匿名管道和命名管道半双工与全双工管道相关函数创建管道总结前言 在Linux操作系统中,进程是执行中的程序的实例。每个进程都有自己的地址空间,数据栈以及其他用于跟踪进程执行的辅助数据。操作系统管理这些进程,并通过调度算法来分享…...

CompletableFuture 基本用法

一、 CompletableFuture简介 CompletableFuture 是 Java 8 引入的一个功能强大的类&#xff0c;用于异步编程和并发处理。它提供了丰富的 API 来处理异步任务的结果&#xff0c;支持函数式编程风格&#xff0c;并允许通过链式调用组合多个异步操作。 二、CompletableFuture中…...

网页如何发布到服务器上

将网页发布到服务器上的过程涉及多个步骤&#xff0c;包括准备阶段、选择托管提供商、发布网站等。12 准备阶段&#xff1a; 确保在本地开发环境中对网站进行了充分的测试&#xff0c;包括功能测试、性能测试和安全测试。 检查Web.config文件&#xff0c;确保所有的配置设置…...

Jenkins简要说明

Jenkins 是一个开源的持续集成和持续部署&#xff08;CI/CD&#xff09;工具&#xff0c;广泛用于自动化软件开发过程中的构建、测试和部署等任务。它是基于Java开发的&#xff0c;因此可以在任何支持Java的平台上运行&#xff0c;并且能够与各种操作系统、开发工具和插件无缝集…...

C# 比较基础知识:最佳实践和技巧

以下是一些在 C# 中进行比较的技巧和窍门的概述。 1. 比较原始类型 对于原始类型&#xff08;int、double、char 等&#xff09;&#xff0c;可以使用标准比较运算符。 int a 5; int b 10; bool isEqual (a b); // false bool isGreater (a > b); // false bool is…...

Ansible 自动化运维实践

随着 IT 基础设施的复杂性不断增加&#xff0c;手动运维已无法满足现代企业对高效、可靠的 IT 运维需求。Ansible 作为一款开源的自动化运维工具&#xff0c;通过简洁易用的 YAML 语法和无代理&#xff08;agentless&#xff09;架构&#xff0c;极大简化了系统配置管理、应用部…...

红队攻防渗透技术实战流程:中间件安全:IISNGINXAPACHETOMCAT

红队攻防渗透实战 1. 中间件安全1.1 中间件-IIS-短文件&解析&蓝屏等1.2 中间件-Nginx-文件解析&命令执行等1.2.1 后缀解析 文件名解析1.2.2 cve_2021_23017 无EXP有POC1.2.3 cve_2017_7529 意义不大1.3 中间件-Apache-RCE&目录遍历&文件解析等1.3.1 cve_20…...

如何卸载宝塔面板?

宝塔官方有提供宝塔面板的卸载命令&#xff0c;使用这个卸载命令&#xff0c;我们就能将宝塔面板卸载掉。 这里有一点需要注意的&#xff0c;如果卸载宝塔面板的同时&#xff0c;也希望将 Nginx、MySQL、PHP 等组件卸载掉&#xff0c;那么我们应该先在宝塔面板里面卸载掉以上软…...

python入门基础知识(错误和异常)

本文部分内容来自菜鸟教程Python 基础教程 | 菜鸟教程 (runoob.com) 本人负责概括总结代码实现。 以此达到快速复习目的 目录 语法错误 异常 异常处理 try/except try/except...else try-finally 语句 抛出异常 用户自定义异常 内置异常类型 常见的标准异常类型 语法…...

迈巴赫S480升级增强现实AR抬头显示hud比普通抬头显示HUD更好用吗

增强AR实景抬头显示HUD&#xff08;Augmented Reality Head-Up Display&#xff09;是一种更高级的驾驶辅助技术&#xff0c;相比于普通抬头显示HUD&#xff0c;它提供了更丰富、更具沉浸感的驾驶体验。以下是它比普通抬头显示HUD多的一些功能&#xff1a; • 信息呈现方式&am…...

vivado、vitis2022安装及其注意事项(省时、省空间)

1、下载 AMD官网-资源与支持-vivado ML开发者工具&#xff0c;或者vitis平台&#xff0c; 下载的时候有个官网推荐web安装&#xff0c;亲测这个耗时非常久&#xff0c;不建议使用&#xff0c;还是直接下载89G的安装包快。 注意&#xff1a;安装vitis平台会默认安装vivado&…...

【自动驾驶】ROS小车系统

文章目录 小车组成轮式运动底盘的组成轮式运动底盘的分类轮式机器人的控制方式感知传感器ROS决策主控ROS介绍ROS的坐标系ROS的单位机器人电气连接变压模块运动底盘的电气连接ROS主控与传感器的电气连接ROS主控和STM32控制器两种控制器的功能运动底盘基本组成电池电机控制器与驱…...

mysql学习——多表查询

多表查询 内连接外连接自连接自连接查询联合查询 子查询 学习黑马MySQL课程&#xff0c;记录笔记&#xff0c;用于复习。 添加外键 alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id);多表查询 select * from emp , dept where emp…...

【Gradio】如何设置 Gradio 数据框的样式

简介 数据可视化是数据分析和机器学习的关键方面。Gradio DataFrame 组件是一种流行的方式&#xff0c;在网络应用程序中显示表格数据&#xff08;特别是以 pandas DataFrame 对象的形式&#xff09;。 本文将探讨 Gradio 的最新增强功能&#xff0c;这些功能允许用户整合 pand…...

【ThreeJS】Threejs +Vue3 开发基础

目前流行的前端3D框架以以Three.js、Babylon.js、A-Frame和ThingJS为例&#xff1a; 1.Three.js 功能&#xff1a; 提供了大量的3D功能&#xff0c;包括基本几何形状、材质、灯光、动画、特效等。 易用性&#xff1a; 功能强大且易于使用&#xff0c;抽象了复杂的底层细节&…...

cocos 如何使用九宫格图片,以及在微信小程序上失效。

1.在图片下方&#xff0c;点击edit。 2.拖动线条&#xff0c;使四角不被拉伸。 3.使用。 其他 在微信小程序上失效&#xff0c;需要将packable合图功能取消掉。...

Spring企业开发核心框架

一、框架前言 1、总体技术体系 单一架构 一个项目&#xff0c;一个工程&#xff0c;导出为一个war包&#xff0c;在一个Tomcat上运行。也叫all in one. 单一架构&#xff0c;项目主要应用技术框架为&#xff1a;Spring&#xff0c;SpringMVC&#xff0c;Mybatis等 分布式架构…...

Scrum团队在迭代中如何处理计划外的工作

认为 Scrum 团队不做计划其实是一个误区&#xff0c;实际上很多 Scrum 团队在冲刺计划会议以及在细化工作项时均会进行详细规划。此外&#xff0c;他们还会创建一个路线图&#xff0c;以便显示他们在多个冲刺中的计划。 Scrum 团队需要经常进行计划&#xff0c;以便在不断变化…...

桌面识别技术革新交互,展厅互动体验步入新时代!

在这股科技浪潮中&#xff0c;物体识别桌作为一种前沿的人机交互设备&#xff0c;其影响力尤为显著。它不仅颠覆了传统展厅内容的交互模式&#xff0c;更以科技之力为观众呈现了一场前所未有的视觉盛宴。那么&#xff0c;接下来&#xff0c;就让我们一起深入探索&#xff0c;物…...

书生·浦语大模型LagentAgentLego智能体应用搭建 第二期

文章目录 智能体概述智能体的定义智能体组成智能体范式 环境配置Lagent&#xff1a;轻量级智能体框架实战Lagent Web Demo用 Lagent 自定义工具 AgentLego&#xff1a;组装智能体“乐高”直接使用AgentLego作为智能体工具使用 用 AgentLego 自定义工具 智能体概述 智能体的定义…...

具有 Hudi、MinIO 和 HMS 的现代数据湖

Apache Hudi 已成为管理现代数据湖的领先开放表格式之一&#xff0c;直接在现代数据湖中提供核心仓库和数据库功能。这在很大程度上要归功于 Hudi 提供了表、事务、更新/删除、高级索引、流式摄取服务、数据聚类/压缩优化和并发控制等高级功能。 我们已经探讨了 MinIO 和 Hudi…...

32.基于分隔符解决黏包和半包

LineBasedFrameDecoder 基于换行/n (linux)或回车换行/r/n(windows)进行分割。 使用LIneBasedFrameDecoder构造方法,需要设定一个最大长度。 如果超过了最大长度,还是没有找到换行符,就这位这个数据段太长了,抛出ToolLongFrameException DelimiterBasedFrameDecoder …...

2024-6-19(沉默springboot)

1.spring开启事务支持 事务在逻辑上是一组操作&#xff0c;要么执行&#xff0c;要不都不执行。主要是针对数据库而言的&#xff0c;比如说 MySQL。 业务场景eg: public void savePosts(PostsParam postsParam) {// 保存文章save(posts);// 处理标签insertOrUpdateTag(posts…...

three.js 第八节 - gltf加载器、解码器

// ts-nocheck // 引入three.js import * as THREE from three // 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls // 导入hdr加载器&#xff08;专门加载hdr的&#xff09; import { RGBELoader } from three/examples/jsm/loaders…...