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

Spring AOP 学习笔记 之 Advice详解

学习材料:https://docs.spring.io/spring-framework/reference/core/aop/ataspectj/advice.html

1. 什么是 Advice(通知)

定义:Advice 是 AOP 的核心概念之一,表示在特定的连接点(Join Point)上执行的代码逻辑。
作用:通过 Advice,可以在方法调用前后、异常抛出时等位置插入自定义逻辑。

2. Advice 的类型

Spring AOP 提供了以下几种类型的 Advice:

2.1 @Before Advice

@Before 注解用于声明前置通知(Before Advice),即在目标方法执行之前执行自定义逻辑。
使用场景:适用于需要在方法执行前进行某些操作的场景,例如日志记录、权限检查等。
参数:@Before 注解可以接受一个切入点表达式,用于指定哪些方法执行前需要应用该Advice。
方法签名:@Before 方法可以有参数,但这些参数必须是Spring AOP支持的参数类型,例如 JoinPoint、ProceedingJoinPoint(仅用于 @Around)、JoinPoint.StaticPart 等。

Pointcut表达式包含在注解里的liline版示例:

@Aspect
public class BeforeExample {@Before("execution(* com.xyz.dao.*.*(..))")public void doAccessCheck() {// ...}
}

 

Before注解里包含的是Pointcut的signature,真正的Pointcut表达式在@Pointcut注解里定义。

@Aspect
public class BeforeExample {@Before("com.xyz.CommonPointcuts.dataAccessOperation()")public void doAccessCheck() {// ...}
}@Aspect
public CommonPointcuts {@Pointcut("execute * com.xyz.dao.*.*(..)")public void dataAccessOperation() {}}

 

2.2 @AfterReturing, @AfterThrowing, @After Advice

在Spring AOP中,@AfterReturning、@AfterThrowing 和 @After 是三种不同的通知(Advice)类型,用于在连接点(Join Point)的不同阶段执行自定义逻辑。以下是它们的详细说明:


@AfterReturning
作用:在目标方法成功执行并返回结果后执行。
使用场景:适用于需要在方法成功执行后进行日志记录、资源清理等操作的场景。
参数:可以接收返回值作为参数,通过returning属性指定参数名。

    @Pointcut("execution(* org.derek.ctroller.*.*(..))")public void log() {}@AfterReturning(pointcut = "log()", returning = "result")public void afterReturning(Object result) {log.info("LogAspect afterReturning ..., result: {}", result);}

@AfterThrowing
作用:在目标方法抛出异常后执行。
使用场景:适用于需要在方法抛出异常时进行异常处理、日志记录等操作的场景。
参数:可以接收异常对象作为参数,通过throwing属性指定参数名。

    @Pointcut("execution(* org.derek.ctroller.*.*(..))")public void log() {}@AfterThrowing(pointcut = "log()", throwing = "exception")public void afterThrowing(Exception exception) {log.info("LogAspect afterThrowing ...", exception);}

@After
作用:无论目标方法是否成功执行,都会在方法执行后执行。
使用场景:适用于需要在方法执行后进行资源清理、日志记录等操作的场景,不关心方法的执行结果。
参数:不接收任何特定参数。

@Slf4j
@Aspect
@Component
public class LogAspect {@Pointcut("execution(* org.derek.ctroller.*.*(..))")public void log() {}@After("log()")public void after() {log.info("LogAspect after ...");}
}

 

2.3 @Around Advice

Around Advice 是一种特殊的Advice,它会在匹配的方法执行前后运行。它有机会在方法执行前后执行自定义逻辑,并且可以决定方法是否执行、何时执行以及如何执行。
使用场景:Around Advice通常用于需要在方法执行前后共享状态的场景,例如启动和停止计时器。
最佳实践:总是使用满足需求的最弱形式的Advice。如果Before Advice已经足够满足需求,则不要使用Around Advice。


返回类型:Around Advice方法的返回类型应为Object。
参数:方法的第一个参数必须是ProceedingJoinPoint类型。
执行方法:在Around Advice方法体内,必须调用proceed()方法来执行目标方法。调用proceed()方法时,如果不带参数,会将调用者原始的参数传递给目标方法。

@Slf4j
@Aspect
@Component
public class LogAspect {@Pointcut("execution(* org.derek.ctroller.*.*(..))")public void log() {}@Around("log()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {log.info("LogAspect around start ...");long start = System.currentMillis();Object result = joinPoint.proceed();log.info("LogAspect around end ...");long end = System.currentMillis();System.out.println("cost time: " + (end-start) + "ms");return result;}
}

3 Advice的执行顺序

3.0 测试环境

使用的springboot测试依赖如下:

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

下面测试的Aspect准备拦截Controller的方法,Controller代码如下: 

@Slf4j
@RestController
public class HelloCtroller {@GetMapping("/hello")public String hello() {log.info("execute method: hello()");return "hello";}@GetMapping("/divide")public Integer divide(@RequestParam("a") Integer a, @RequestParam("b") Integer b) {log.info("execute method: divide(), a: {}, b: {}", a, b);return a/b;}
}

 

3.1 单个Aspect的各Advice执行顺序

可以看到我们LogAspect的整体代码如下:

@Slf4j
@Aspect
@Component
public class LogAspect {@Pointcut("execution(* org.derek.ctroller.*.*(..))")public void log() {}@Around("log()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {log.info("LogAspect around start ...");Object result = joinPoint.proceed();log.info("LogAspect around end ...");return result;}@Before("log()")public void before() {log.info("LogAspect before ...");}@AfterReturning(pointcut = "log()", returning = "result")public void afterReturning(Object result) {log.info("LogAspect afterReturning ..., result: {}", result);}@AfterThrowing(pointcut = "log()", throwing = "exception")public void afterThrowing(Exception exception) {log.info("LogAspect afterThrowing ...", exception);}@After("log()")public void after() {log.info("LogAspect after ...");}
}

 

3.1.1 方法正常返回的执行顺序

HelloController.hello() 方法会正常执行,并返回String结果。

我们执行 /hello地址的请求:

http://localhost:8080/hello

后台打印的切面日志如下:

2025-04-15T13:58:26.858+08:00  INFO 25536 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
2025-04-15T13:58:26.888+08:00  INFO 25536 --- [nio-8080-exec-1] org.derek.aspect.LogAspect               : LogAspect around start ...
2025-04-15T13:58:26.889+08:00  INFO 25536 --- [nio-8080-exec-1] org.derek.aspect.LogAspect               : LogAspect before ...
2025-04-15T13:58:26.889+08:00  INFO 25536 --- [nio-8080-exec-1] org.derek.ctroller.HelloCtroller         : execute method: hello()
2025-04-15T13:58:26.889+08:00  INFO 25536 --- [nio-8080-exec-1] org.derek.aspect.LogAspect               : LogAspect afterReturning ..., result: hello
2025-04-15T13:58:26.889+08:00  INFO 25536 --- [nio-8080-exec-1] org.derek.aspect.LogAspect               : LogAspect after ...
2025-04-15T13:58:26.889+08:00  INFO 25536 --- [nio-8080-exec-1] org.derek.aspect.LogAspect               : LogAspect around end ...

调用方法的正常返回顺序如下:

@Around start --> @Before advice --> orginal method  --> @AfterReturing --> @After --> @Around end.

3.1.2 方法碰到异常的执行顺序

HelloController.divide(Integer a, Integer b)方法, 当b=0的时候,就会抛出除零异常。

http://localhost:8080/divide?a=2&b=0

执行的Aspect拦截日志如下:

2025-04-15T14:05:03.612+08:00  INFO 25536 --- [nio-8080-exec-5] org.derek.aspect.LogAspect               : LogAspect around start ...
2025-04-15T14:05:03.613+08:00  INFO 25536 --- [nio-8080-exec-5] org.derek.aspect.LogAspect               : LogAspect before ...
2025-04-15T14:05:03.613+08:00  INFO 25536 --- [nio-8080-exec-5] org.derek.ctroller.HelloCtroller         : execute method: divide(), a: 2, b: 0
2025-04-15T14:05:03.613+08:00  INFO 25536 --- [nio-8080-exec-5] org.derek.aspect.LogAspect               : LogAspect afterThrowing ...

java.lang.ArithmeticException: / by zero
    at org.derek.ctroller.HelloCtroller.divide(HelloCtroller.java:25) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:355) ~[spring-aop-6.1.15.jar:6.1.15]

2025-04-15T14:05:03.620+08:00  INFO 25536 --- [nio-8080-exec-5] org.derek.aspect.LogAspect               : LogAspect after ...
2025-04-15T14:05:03.622+08:00 ERROR 25536 --- [nio-8080-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.ArithmeticException: / by zero] with root cause

java.lang.ArithmeticException: / by zero
 

可以看到异常情况下,拦截执行顺序如下:

@Around start --> @Before Advice --> orginal method --> @AfterThrowing --> @After (--> @Around end  因为抛出异常这里不再执行)

3.2 多个Aspect的各Advice的执行顺序

1. 默认执行顺序
在 Spring AOP 中,默认情况下,Aspect 的执行顺序是未定义的。如果多个 Aspect 匹配同一个连接点(Join Point),它们的执行顺序可能会根据依赖注入的顺序、类加载顺序或其他因素动态决定。

2. 通过 @Order 注解控制顺序
可以使用 @Order 注解来显式指定 Aspect 的优先级。
数字越小,优先级越高,越先执行。
示例代码:

import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;@Aspect
@Order(1) // 优先级最高
public class FirstAspect {// 定义切入点和通知逻辑
}@Aspect
@Order(2) // 次优先级
public class SecondAspect {// 定义切入点和通知逻辑
}

3. 通过实现 Ordered 接口
如果不想使用 @Order 注解,可以实现 org.springframework.core.Ordered 接口,并重写 getOrder() 方法。
示例代码:

import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.Ordered;@Aspect
public class FirstAspect implements Ordered {@Overridepublic int getOrder() {return 1; // 优先级最高}
}@Aspect
public class SecondAspect implements Ordered {@Overridepublic int getOrder() {return 2; // 次优先级}
}

这里为了测试实际的Aspect执行顺序,我们使用注解@Order的方式定义了两个切面:

 ControllerAspect.java, 顺序为1.

@Slf4j
@Aspect
@Component
@Order(1) // 优先级,越小越先执行
public class CtrollerAspect {@Pointcut("execution(* org.derek.ctroller.*.*(..))")public void controller() {System.out.println("log");}@Around("controller()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {log.info("around advice start ...");Object proceed = joinPoint.proceed();log.info("around advice end ...");return proceed;}@Before("controller()")public void before() {log.info("before advice ...");}@AfterReturning(pointcut = "controller()", returning = "result")public void afterReturning(Object result) {log.info("afterReturning advice ..., result: {}", result);}@AfterThrowing(pointcut = "controller()", throwing = "exception")public void afterThrowing(Exception exception) {log.info("afterThrowing advice ...", exception);}@After("controller()")public void after() {log.info("after advice ...");}
}

LogAspect.java, 顺序为2.

@Slf4j
@Aspect
@Component
@Order(2)
public class LogAspect {@Pointcut("execution(* org.derek.ctroller.*.*(..))")public void log() {}@Around("log()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {log.info("LogAspect around start ...");Object result = joinPoint.proceed();log.info("LogAspect around end ...");return result;}@Before("log()")public void before() {log.info("LogAspect before ...");}@AfterReturning(pointcut = "log()", returning = "result")public void afterReturning(Object result) {log.info("LogAspect afterReturning ..., result: {}", result);}@AfterThrowing(pointcut = "log()", throwing = "exception")public void afterThrowing(Exception exception) {log.info("LogAspect afterThrowing ...", exception);}@After("log()")public void after() {log.info("LogAspect after ...");}
}

执行相同的hello方法,调用日志如下:

2025-04-15T13:52:45.672+08:00  INFO 32288 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
2025-04-15T13:52:45.705+08:00  INFO 32288 --- [nio-8080-exec-1] org.derek.aspect.CtrollerAspect          : around advice start ...
2025-04-15T13:52:45.705+08:00  INFO 32288 --- [nio-8080-exec-1] org.derek.aspect.CtrollerAspect          : before advice ...
2025-04-15T13:52:45.705+08:00  INFO 32288 --- [nio-8080-exec-1] org.derek.aspect.LogAspect               : LogAspect around start ...
2025-04-15T13:52:45.705+08:00  INFO 32288 --- [nio-8080-exec-1] org.derek.aspect.LogAspect               : LogAspect before ...
2025-04-15T13:52:45.705+08:00  INFO 32288 --- [nio-8080-exec-1] org.derek.ctroller.HelloCtroller         : execute method: hello()
2025-04-15T13:52:45.705+08:00  INFO 32288 --- [nio-8080-exec-1] org.derek.aspect.LogAspect               : LogAspect afterReturning ..., result: hello
2025-04-15T13:52:45.707+08:00  INFO 32288 --- [nio-8080-exec-1] org.derek.aspect.LogAspect               : LogAspect after ...
2025-04-15T13:52:45.707+08:00  INFO 32288 --- [nio-8080-exec-1] org.derek.aspect.LogAspect               : LogAspect around end ...
2025-04-15T13:52:45.707+08:00  INFO 32288 --- [nio-8080-exec-1] org.derek.aspect.CtrollerAspect          : afterReturning advice ..., result: hello
2025-04-15T13:52:45.707+08:00  INFO 32288 --- [nio-8080-exec-1] org.derek.aspect.CtrollerAspect          : after advice ...
2025-04-15T13:52:45.707+08:00  INFO 32288 --- [nio-8080-exec-1] org.derek.aspect.CtrollerAspect          : around advice end ...

可以看到,多个切面执行顺序如下:

1) @Order(1)的切面方法  @Around start --> @Before Advice

2) @Order(2)的切面方法 @Around start --> @Before Advice 

3) 执行原始的方法 original method

4) @Order(2)的切面方法 @AfterReturning/@AfterThrowing --> @After --> @Adround end

5)@Order(1)的切面方法 @AfterReturning/@AfterThrowing --> @After --> @Adround end

相关文章:

Spring AOP 学习笔记 之 Advice详解

学习材料&#xff1a;https://docs.spring.io/spring-framework/reference/core/aop/ataspectj/advice.html 1. 什么是 Advice&#xff08;通知&#xff09; 定义&#xff1a;Advice 是 AOP 的核心概念之一&#xff0c;表示在特定的连接点&#xff08;Join Point&#xff09;上…...

【Linux系统】进程地址空间

命令行参数 int main (int argc, char* argv[]) 命令行参数列表 argc&#xff1a;参数的个数argv&#xff1a;参数的清单 int main (int argc, char* argv[]) {printf("argc: %d\n",argc);for(int i 0; i < argc; i){printf("argv[%d] : %s \n", i…...

记录学习的第二十六天

还是每日一题。 今天这道题有点难度&#xff0c;我看着题解抄的。 之后做了两道双指针问题。 这道题本来是想用纯暴力做的&#xff0c;结果出错了。&#x1f613;...

python成功解决AttributeError: can‘t set attribute ‘lines‘

文章目录 报错信息与原因分析解决方法示例代码代码解释总结 报错信息与原因分析 在使用 matplotlib绘图时&#xff0c;若尝试使用 ax.lines []来清除图表中的线条&#xff0c;会遇到AttributeError: can’t set attribute错误。这是因为 ax.lines是一个只读属性&#xff0c;不…...

测试 认识bug

一、软件测试生命周期与测试模型 1. 软件&#xff08;开发&#xff09;生命周期&#xff1a;包括需求分析、计划、设计、编码、测试、运行维护阶段。需求分析是起始点&#xff0c;明确用户需求&#xff0c;后续阶段依此展开 。例如开发电商软件&#xff0c;需求分析阶段确定商品…...

Mysql主从复制有哪些方式

MySQL 主从复制主要有以下几种方式&#xff0c;根据不同的分类标准&#xff08;如同步机制、数据复制格式、拓扑结构等&#xff09;可以分为&#xff1a; 一、按同步机制分类 1. 异步复制 (Asynchronous Replication) 原理&#xff1a;主库提交事务后&#xff0c;立即返回给客…...

如何建立可复用的项目管理模板

建立可复用的项目管理模板能够显著提高项目执行效率、减少重复劳动、确保项目管理标准化。在企业中&#xff0c;项目管理往往涉及多个步骤和多个团队&#xff0c;然而每次开始一个新项目时&#xff0c;如果都从头开始设计流程和文档&#xff0c;势必浪费大量的时间和精力。通过…...

Spring Cloud 服务间调用深度解析

前言 在构建微服务架构时&#xff0c;服务间的高效通信是至关重要的。Spring Cloud 提供了一套完整的解决方案来实现服务间的调用、负载均衡、服务发现等功能。本文将深入探讨 Spring Cloud 中服务之间的调用机制&#xff0c;并通过源码片段和 Mermaid 图表帮助读者更好地理解…...

如何使用通义灵码玩转Docker - AI助手提升开发效率

一、引言 Docker 作为一种流行的虚拟化技术&#xff0c;能够帮助开发者快速搭建所需的运行环境。然而&#xff0c;对于初学者来说&#xff0c;掌握 Docker 的基本概念和使用方法可能会遇到一些挑战。本文将介绍如何利用通义灵码这一智能编码助手&#xff0c;帮助你更高效地学习…...

GGML源码逐行调试(下)

目录 前言1. 简述2. 预分配计算图内存2.1 创建图内存分配器2.2 构建最坏情况的计算图2.3 预留计算图内存 3. 分词4. 模型推理与生成4.1 模型推理4.2 采样 结语下载链接参考 前言 学习 UP 主 比飞鸟贵重的多_HKL 的 GGML源码逐行调试 视频&#xff0c;记录下个人学习笔记&#x…...

uniapp的通用页面及组件基本封装

1.基本布局页面 适用于自定义Navbar头部 <template><view class"bar" :style"{height : systemInfo.statusBarHeight px, background: param.barBgColor }"></view><view class"headBox" :style"{ height: param.h…...

YOLO11改进——融合BAM注意力机制增强图像分类与目标检测能力

深度学习在计算机视觉领域的应用取得了显著进展,尤其是在目标检测(Object Detection)和图像分类(Image Classification)任务中。YOLO(You Only Look Once)系列算法凭借其高效的单阶段检测框架和卓越的实时性能,成为目标检测领域的研究热点。然而,随着应用场景的复杂化…...

Spring Boot循环依赖全解析:原理、解决方案与最佳实践

&#x1f6a8; Spring Boot循环依赖全解析&#xff1a;原理、解决方案与最佳实践 #SpringBoot核心 #依赖注入 #设计模式 #性能优化 一、循环依赖的本质与危害 1.1 什么是循环依赖&#xff1f; 循环依赖指两个或多个Bean相互直接或间接引用&#xff0c;形成闭环依赖关系。 典…...

力扣 283 移动零的两种高效解法详解

目录 方法一&#xff1a;两次遍历法 方法二&#xff1a;单次遍历交换法 两种方法对比 在解决数组中的零移动到末尾的问题时&#xff0c;我们需要保持非零元素的顺序&#xff0c;并原地修改数组。以下是两种高效的解法及其详细分析。 方法一&#xff1a;两次遍历法 思路分析…...

「2025AIGC终极形态」AI系统源码:文本→图像→音乐→视频生成

—从技术痛点到企业级部署&#xff0c;手把手实现全流程AI内容工厂 行业核心痛点&#xff1a;为什么需要多模态AIGC系统&#xff1f; 1. 工具割裂&#xff0c;效率低下 传统流程&#xff1a; 文案&#xff08;ChatGPT&#xff09;→ 配图&#xff08;Midjourney&#xff09;→…...

使用CS Roofline Toolkit测量带宽

使用CS Roofline Toolkit测量带宽 工程下载&#xff1a;使用CS Roofline Toolkit测量带宽-案例工程文件&#xff0c;也可以按照下面的说明使用git clone下载 目录 使用CS Roofline Toolkit测量带宽0、Roofline模型理解1、CS Roofline Toolkit下载1.1、设置代理1.2、git clone下…...

L1-4 拯救外星人

题目 你的外星人朋友不认得地球上的加减乘除符号&#xff0c;但是会算阶乘 —— 正整数 N 的阶乘记为 “N!”&#xff0c;是从 1 到 N 的连乘积。所以当他不知道“57”等于多少时&#xff0c;如果你告诉他等于“12!”&#xff0c;他就写出了“479001600”这个答案。 本题就请你…...

现代c++获取linux系统名称

现代c获取linux系统名称 前言一、使用命令获取操作系统名称二、使用c代码获取操作系统名称三、验证四、总结 前言 本文介绍一种使用c获取当前操作系统名称的方法 一、使用命令获取操作系统名称 在linux系统中可以使用uname或者uname -s命令来获取当前操作系统名称&#xff0c…...

力扣刷题HOT100——53.最大子数组和

给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组是数组中的一个连续部分。 示例 1&#xff1a; 输入&#xff1a;nums [-2,1,-3,4,-1,2,1,-5,4] 输出&#xff1a;6…...

Java面试黄金宝典48

1. C++ 的拷贝构造函数,深拷贝和浅拷贝 定义 拷贝构造函数:在 C++ 里,拷贝构造函数属于特殊的构造函数,其功能是使用一个已存在的对象来初始化一个新对象。当对象以值传递的方式作为参数传给函数、函数返回对象、用一个对象初始化另一个对象时,拷贝构造函数会被调用。浅拷…...

QuickAPI 核心能力解析:构建数据服务化的三位一体生态

在企业数据资产化运营的进程中&#xff0c;如何打破数据开发与共享的效率瓶颈&#xff0c;实现从 “数据可用” 到 “数据好用” 的跨越&#xff1f;麦聪软件的 QuickAPI 给出了系统性答案。作为 SQL2API 理念的标杆产品&#xff0c;QuickAPI 通过SQL 编辑器、数据 API、数据市…...

ES和MySQL概念对比

基本概念 ES和MySQL都属于数据库&#xff0c;不过各有各的特性&#xff0c;大致使用方法与MySQL类似并无区别。 MySQL&#xff1a;擅长事务持有ACID的特性&#xff0c;确保数据的一致性和安全。 ES&#xff1a;持有倒排索引&#xff0c;适合海量数据搜索和分析。 ES和MySQL如何…...

Spring如何解决项目中的循环依赖问题?

目录 什么是循环依赖&#xff1f; 如何解决&#xff1f; 采用两级缓存解决 需要AOP的Bean的循环依赖问题&#xff1f; 三级缓存解决 什么是循环依赖&#xff1f; 循环依赖就是Spring在初始化Bean时两个不同的Bean你依赖我&#xff0c;我依赖你的情况 例如A依赖B&#xf…...

计算机系统---烤机(性能测评)

计算机烤机 一、烤机的定义与核心目的 烤机&#xff08;Burn-in Test&#xff09; 是通过对计算机硬件施加持续高负载&#xff0c;模拟极端运行环境&#xff0c;以验证硬件稳定性、性能极限、散热能力及潜在缺陷的测试方法。核心目标包括&#xff1a; 硬件稳定性验证&#x…...

Android开发过程中遇到的SELINUX权限问题

1、selinux权限一般问题 问题详情 log输出如下所示&#xff1a; 01-01 00:00:12.210 1 1 I auditd : type1107 audit(0.0:33): uid0 auid4294967295 ses4294967295 subju:r:init:s0 msg‘avc: denied{ set } for propertypersist.sys.locale pid476 uid1000 gid1000 scontext…...

[Java实战经验]链式编程与Builder模式

目录 链式编程Builder模式 链式编程 链式编程&#xff08;Fluent AP&#xff09;是一种编程风格&#xff0c;它通过在同一个对象上连续调用多个方法来执行一系列操作&#xff08;让方法返回对象本身&#xff08;return this&#xff09;&#xff09;。这种风格的编程使代码更加…...

Windows系统docker desktop安装(学习记录)

目前在学习docker&#xff0c;在网上扒了很多老师的教程&#xff0c;终于装好了&#xff0c;于是决定再装一遍做个记录&#xff0c;省的以后再这么麻烦 一&#xff1a;什么是docker Docker 是一个开源的应用容器引擎&#xff0c;它可以让开发者打包他们的应用以及依赖包到一个…...

MIP-Splatting:全流程配置与自制数据集测试【ubuntu20.04】【2025最新版】

一、引言 在计算机视觉和神经渲染领域&#xff0c;3D场景重建与渲染一直是热门研究方向。近期&#xff0c;3D高斯散射&#xff08;3D Gaussian Splatting&#xff09;因其高效的渲染速度和优秀的视觉质量而受到广泛关注。然而&#xff0c;当处理大型复杂场景时&#xff0c;这种…...

怎样完成本地模型知识库检索问答RAG

怎样完成本地模型知识库检索问答RAG 目录 怎样完成本地模型知识库检索问答RAG使用密集检索器和系数检索器混合方式完成知识库相似检索1. 导入必要的库2. 加载文档3. 文本分割4. 初始化嵌入模型5. 创建向量数据库6. 初始化大语言模型7. 构建问答链8. 提出问题并检索相关文档9. 合…...

XCTF-web(三)

xff_referer 拦截数据包添加&#xff1a;X-Forwarded-For: 123.123.123.123 添加&#xff1a;Referer: https://www.google.com baby_web 提示&#xff1a;想想初始页面是哪个 查看/index.php simple_js 尝试万能密码&#xff0c;没有成功&#xff0c;在源码中找到如下&#xf…...