Springboot如何使用面向切面编程AOP?
Springboot如何使用面向切面编程AOP?
在 Spring Boot 中使用面向切面编程(AOP)非常简单,Spring Boot 提供了对 AOP 的自动配置支持。以下是详细的步骤和示例,帮助你快速上手 Spring Boot 中的 AOP。
1. 添加依赖
首先,在 pom.xml
(Maven)或 build.gradle.kts
(Gradle)中添加 Spring Boot Starter AOP 依赖:
Maven
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Gradle-Kotlin build.gradle.kts
dependencies {implementation("org.springframework.boot:spring-boot-starter-aop")
}
implementation("org.springframework.boot:spring-boot-starter-aop")
Gradle-Groovy build.gradle
dependencies {implementation 'org.springframework.boot:spring-boot-starter-aop'
}
implementation 'org.springframework.boot:spring-boot-starter-aop'
2. 编写切面类
切面类是一个普通的 Spring Bean,使用 @Aspect
注解标记。切面类中定义了切点(Pointcut)和通知(Advice)。
示例:记录方法执行日志的切面
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;@Aspect // 标记为切面类
@Component // 标记为 Spring Bean
public class LoggingAspect {// 定义切点:拦截 com.example.service 包下的所有方法@Pointcut("execution(* com.example.service.*.*(..))")public void serviceMethods() {}// 前置通知:在目标方法执行前执行@Before("serviceMethods()")public void logBeforeMethod() {System.out.println("方法即将执行...");}
}
3. 定义目标服务类
编写一个普通的 Spring 服务类,作为 AOP 的目标对象。
示例:用户服务类
import org.springframework.stereotype.Service;@Service
public class UserService {public void createUser(String name) {System.out.println("创建用户: " + name);}public void deleteUser(String name) {System.out.println("删除用户: " + name);}
}
4. 启用 AOP 支持
Spring Boot 默认会自动启用 AOP 支持,无需额外配置。如果需要手动启用,可以在主应用类上添加 @EnableAspectJAutoProxy
注解:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@SpringBootApplication
@EnableAspectJAutoProxy // 启用 AOP 支持
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}
5. 运行并验证
启动 Spring Boot 应用,调用 UserService
的方法,观察切面是否生效。
示例:调用服务方法
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;@Component
public class AppRunner implements CommandLineRunner {@Autowiredprivate UserService userService;@Overridepublic void run(String... args) throws Exception {userService.createUser("Alice");userService.deleteUser("Bob");}
}
输出结果
方法即将执行...
创建用户: Alice
方法即将执行...
删除用户: Bob
6. 常用 AOP 注解
Spring AOP 提供了多种通知类型,以下是常用的注解:
注解 | 说明 |
---|---|
@Before | 在目标方法执行前执行。 |
@After | 在目标方法执行后执行(无论是否抛出异常)。 |
@AfterReturning | 在目标方法成功返回后执行。 |
@AfterThrowing | 在目标方法抛出异常后执行。 |
@Around | 环绕通知,可以控制目标方法的执行(如修改参数、返回值或捕获异常)。 |
示例:环绕通知
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;@Aspect
@Component
public class TimingAspect {@Around("execution(* com.example.service.*.*(..))")public Object measureExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {long startTime = System.currentTimeMillis();Object result = joinPoint.proceed(); // 执行目标方法long endTime = System.currentTimeMillis();System.out.println("方法执行时间: " + (endTime - startTime) + "ms");return result;}
}
7. 切点表达式
切点表达式用于定义拦截的目标方法。以下是常见的表达式示例:
表达式 | 说明 |
---|---|
execution(* com.example.service.*.*(..)) | 拦截 com.example.service 包下的所有方法。 |
execution(* com.example.service.UserService.*(..)) | 拦截 UserService 类中的所有方法。 |
execution(* com.example.service.*.create*(..)) | 拦截 com.example.service 包下以 create 开头的方法。 |
@annotation(com.example.LogExecutionTime) | 拦截带有 @LogExecutionTime 注解的方法。 |
自定义注解示例
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {}
在方法上使用注解:
@Service
public class UserService {@LogExecutionTimepublic void createUser(String name) {System.out.println("创建用户: " + name);}
}
在切面中拦截注解:
@Aspect
@Component
public class LogExecutionTimeAspect {@Around("@annotation(com.example.LogExecutionTime)")public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {long startTime = System.currentTimeMillis();Object result = joinPoint.proceed();long endTime = System.currentTimeMillis();System.out.println("方法执行时间: " + (endTime - startTime) + "ms");return result;}
}
8. 总结
- Spring Boot 通过
spring-boot-starter-aop
提供了对 AOP 的自动支持。 - 使用
@Aspect
定义切面类,结合@Before
、@After
、@Around
等注解实现通知。 - 切点表达式(
execution
)用于定义拦截的目标方法。 - 可以通过自定义注解实现更灵活的切面逻辑。
通过以上步骤,你可以在 Spring Boot 中轻松实现面向切面编程(AOP),增强代码的可维护性和可扩展性。
在Spring Boot中使用面向切面编程(AOP)通常涉及以下几个步骤:
1. 引入依赖
虽然Spring Boot的spring-boot-starter
已经包含了AOP的依赖,但为了确保AOP功能被正确启用,你可以在pom.xml
中显式添加spring-boot-starter-aop
依赖(尽管这通常是可选的,因为spring-boot-starter-web
等常用starter已经包含了它)。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2. 启用AOP
在Spring Boot中,你通常不需要显式启用AOP,因为@SpringBootApplication
注解已经包含了@EnableAspectJAutoProxy
,后者负责启用AOP代理。但是,如果你想要自定义AOP代理的行为(例如,使用CGLIB而不是JDK动态代理),你可以通过添加@EnableAspectJAutoProxy
注解并设置其属性来实现。
@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass = true) // 使用CGLIB代理
public class MySpringBootApplication {public static void main(String[] args) {SpringApplication.run(MySpringBootApplication.class, args);}
}
然而,在大多数情况下,默认设置就足够了。
3. 定义切面类
切面类是一个用@Aspect
注解标记的类,它包含了切点(pointcut)和通知(advice)。
- 切点:定义了哪些方法将被拦截。
- 通知:定义了拦截到方法时要执行的操作。
@Aspect
@Component
public class MyAspect {// 定义一个切点,匹配所有com.example.service包下的所有方法@Pointcut("execution(* com.example.service..*(..))")public void myPointcut() {// 这是一个空方法,仅用于定义切点表达式}// 在方法执行之前执行@Before("myPointcut()")public void beforeAdvice(JoinPoint joinPoint) {System.out.println("Before method: " + joinPoint.getSignature());}// 在方法执行之后执行(无论是否抛出异常)@After("myPointcut()")public void afterAdvice(JoinPoint joinPoint) {System.out.println("After method: " + joinPoint.getSignature());}// 在方法执行之后执行(仅当方法正常返回时)@AfterReturning(pointcut = "myPointcut()", returning = "result")public void afterReturningAdvice(JoinPoint joinPoint, Object result) {System.out.println("After returning method: " + joinPoint.getSignature() + " with result: " + result);}// 在方法抛出异常时执行@AfterThrowing(pointcut = "myPointcut()", throwing = "exception")public void afterThrowingAdvice(JoinPoint joinPoint, Throwable exception) {System.out.println("After throwing method: " + joinPoint.getSignature() + " with exception: " + exception);}// 环绕通知,可以在方法执行前后自定义逻辑@Around("myPointcut()")public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("Before proceeding method: " + joinPoint.getSignature());Object result = joinPoint.proceed(); // 执行目标方法System.out.println("After proceeding method: " + joinPoint.getSignature() + " with result: " + result);return result;}
}
4. 应用切面
一旦你定义了切面类并将其作为Spring组件(通过@Component
注解)注册到Spring容器中,Spring AOP将自动应用这些切面到匹配的bean上。
注意事项
- 切面类本身必须是一个Spring管理的bean,因此通常会在切面类上使用
@Component
或其他相关的Spring注解。 - 切点表达式定义了哪些方法将被拦截。你可以使用AspectJ的切点表达式语言(Pointcut Expression Language, PEL)来编写复杂的切点表达式。
- 通知方法可以有参数,这些参数可以是
JoinPoint
、ProceedingJoinPoint
(对于环绕通知)或任何由切点表达式捕获的参数(通过@Args
注解)。 - 环绕通知必须处理目标方法的调用(通过
ProceedingJoinPoint.proceed()
),并且可以返回结果或抛出异常。
通过以上步骤,你就可以在Spring Boot项目中成功使用AOP来实现横切关注点(如日志记录、事务管理、权限校验等)的分离。
在 Spring Boot 中使用面向切面编程(AOP)可以帮助你分离横切关注点,如日志记录、事务管理等,从主要业务逻辑中分离出来。Spring AOP 是基于代理的实现,默认情况下支持方法级别的拦截。下面是如何在 Spring Boot 应用中配置和使用 AOP 的步骤:
1. 添加依赖
首先,确保你的 build.gradle
或 pom.xml
文件中包含了 spring-boot-starter-aop 依赖。
对于 Gradle,添加如下依赖到你的 build.gradle
文件:
dependencies {implementation 'org.springframework.boot:spring-boot-starter-aop'
}
对于 Maven,在你的 pom.xml
文件中添加:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2. 启用 AOP 支持
Spring Boot 自动配置了 AOP 支持,所以通常不需要额外的手动配置。但是,如果你的应用有多个配置类,确保它们被正确扫描到。一般情况下,只需保证主应用程序类或配置类上包含 @EnableAspectJAutoProxy
注解(尽管大多数情况下自动配置已经足够)。
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration
@EnableAspectJAutoProxy
public class AopConfig {
}
不过,如果你只是简单地使用 Spring Boot,并且没有特别复杂的配置需求,这个注解通常是不必要的,因为 Spring Boot 已经为你自动启用了 AOP 支持。
3. 创建一个切面
创建一个类并使用 @Aspect
注解标记它。然后,定义切入点(Pointcut)和通知(Advice),例如前置通知(@Before
)、后置通知(@After
)、返回通知(@AfterReturning
)、异常通知(@AfterThrowing
)和环绕通知(@Around
)。
示例代码:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;@Aspect
@Component
public class LoggingAspect {@Before("execution(* com.example.demo.service.*.*(..))")public void beforeMethodExecution() {System.out.println("A method in the service layer is about to be called.");}
}
4. 定义切入点表达式
上述例子中的 "execution(* com.example.demo.service.*.*(..))"
是一个切入点表达式,表示匹配 com.example.demo.service
包下的所有类的所有方法。你可以根据需要调整此表达式来精确控制哪些方法会被拦截。
5. 测试你的切面
最后,编写一些测试用例或者运行你的应用来验证 AOP 切面是否按预期工作。确保目标方法被调用时,相应的通知也会被执行。
通过以上步骤,你应该能够在 Spring Boot 应用中成功配置并使用 AOP。这种方式不仅能够帮助你清晰地分离关注点,还能使代码更加简洁和易于维护。
在 Spring Boot 中使用面向切面编程(AOP)可以高效地实现日志记录、事务管理、权限校验等横切关注点。以下是 详细步骤和实际应用场景 的总结:
1. 添加依赖
Spring Boot 默认通过 spring-boot-starter-aop
提供对 AOP 的自动配置支持:
Maven
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Gradle
dependencies {implementation("org.springframework.boot:spring-boot-starter-aop")
}
2. 编写切面类
切面类需用 @Aspect
和 @Component
注解标记,定义切点和通知。
示例:日志记录切面
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;@Aspect
@Component
public class LoggingAspect {// 定义切点:拦截 service 包下的所有方法@Pointcut("execution(* com.example.service.*.*(..))")public void serviceMethods() {}// 前置通知:方法执行前记录日志@Before("serviceMethods()")public void logMethodStart() {System.out.println("方法开始执行...");}// 后置通知:方法执行后记录日志(无论是否异常)@After("serviceMethods()")public void logMethodEnd() {System.out.println("方法执行结束。");}// 环绕通知:计算方法执行时间@Around("serviceMethods()")public Object measureTime(ProceedingJoinPoint joinPoint) throws Throwable {long start = System.currentTimeMillis();Object result = joinPoint.proceed(); // 执行目标方法long end = System.currentTimeMillis();System.out.println("方法执行耗时: " + (end - start) + "ms");return result;}
}
3. 定义目标服务
编写一个普通的 Spring Bean 作为切面拦截的目标。
示例:用户服务
@Service
public class UserService {public void createUser(String name) {System.out.println("创建用户: " + name);}
}
4. 验证效果
调用 UserService
的方法时,切面逻辑自动生效:
@SpringBootApplication
public class Application {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);UserService userService = context.getBean(UserService.class);userService.createUser("Alice");}
}
输出结果
方法开始执行...
创建用户: Alice
方法执行结束。
方法执行耗时: 2ms
5. 核心注解详解
(1) 切点表达式(Pointcut)
- 语法:
execution(修饰符 返回类型 包名.类名.方法名(参数类型))
- 常用示例:
execution(* com.example.service.*.*(..))
:拦截service
包下所有类的所有方法。execution(* com.example.service.UserService.create*(..))
:拦截UserService
中以create
开头的方法。@annotation(com.example.LogTrack)
:拦截带有@LogTrack
注解的方法。
(2) 通知类型(Advice)
注解 | 说明 |
---|---|
@Before | 目标方法执行前触发。 |
@After | 目标方法执行后触发(无论是否抛出异常)。 |
@AfterReturning | 目标方法成功返回后触发(可获取返回值)。 |
@AfterThrowing | 目标方法抛出异常后触发(可捕获异常对象)。 |
@Around | 包裹目标方法,可控制方法执行、修改参数或返回值。 |
示例:获取方法参数和返回值
@Aspect
@Component
public class DataAspect {@AfterReturning(pointcut = "execution(* com.example.service.*.*(..))",returning = "result")public void logResult(Object result) {System.out.println("方法返回值: " + result);}@Before("execution(* com.example.service.*.*(..)) && args(name)")public void logArgument(String name) {System.out.println("方法参数: " + name);}
}
6. 高级用法
(1) 自定义注解实现切面
定义注解标记需要拦截的方法,提高代码可读性。
步骤1:定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogTrack {}
步骤2:在方法上使用注解
@Service
public class OrderService {@LogTrackpublic void placeOrder(String orderId) {System.out.println("下单成功: " + orderId);}
}
步骤3:切面拦截注解
@Aspect
@Component
public class LogTrackAspect {@Around("@annotation(com.example.LogTrack)")public Object trackMethod(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("开始追踪方法...");Object result = joinPoint.proceed();System.out.println("追踪结束。");return result;}
}
(2) 处理异常
在 @AfterThrowing
中捕获并处理异常。
@Aspect
@Component
public class ExceptionAspect {@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))",throwing = "ex")public void handleException(Exception ex) {System.out.println("捕获异常: " + ex.getMessage());// 发送报警邮件或记录日志}
}
7. 常见问题与解决
问题1:切面未生效
- 原因:
- 切面类未被 Spring 管理(缺少
@Component
)。 - 切点表达式未匹配到目标方法。
- 目标方法未被 Spring 代理(如直接通过
new
创建对象)。
- 切面类未被 Spring 管理(缺少
- 解决:
- 确保切面类添加了
@Component
。 - 使用
@Autowired
获取 Bean,而非直接实例化。
- 确保切面类添加了
问题2:环绕通知未调用 proceed()
- 现象:目标方法未执行。
- 解决:在
@Around
方法中必须调用joinPoint.proceed()
。
8. 实际应用场景
- 日志记录:自动记录方法入参、返回值、执行时间。
- 事务管理:结合
@Transactional
实现声明式事务。 - 权限校验:在方法执行前检查用户权限。
- 性能监控:统计接口耗时,优化慢查询。
- 缓存管理:在方法执行前后操作缓存(如 Redis)。
总结
Spring Boot 通过简化配置和自动代理机制,使得 AOP 的实现非常便捷。核心步骤:
- 添加
spring-boot-starter-aop
依赖。 - 使用
@Aspect
和@Component
定义切面类。 - 通过切点表达式精准定位目标方法。
- 选择合适的通知类型(
@Before
、@Around
等)实现横切逻辑。
掌握 AOP 后,可以大幅减少重复代码,提升系统的可维护性和扩展性。
相关文章:
Springboot如何使用面向切面编程AOP?
Springboot如何使用面向切面编程AOP? 在 Spring Boot 中使用面向切面编程(AOP)非常简单,Spring Boot 提供了对 AOP 的自动配置支持。以下是详细的步骤和示例,帮助你快速上手 Spring Boot 中的 AOP。 1. 添加依赖 首先ÿ…...
ThreadLocal源码解析
文章目录 一、概述二、get()方法三、set()方法四、可能导致的内存泄漏问题五、remove六、思考:为什么要将ThreadLocalMap的value设置为强引用? 一、概述 ThreadLocal是线程私有的,独立初始化的变量副本。存放在和线程进行绑定的ThreadLocalMa…...
Maven的单元测试
1. 单元测试的基本概念 单元测试(Unit Testing) 是一种软件测试方法,专注于测试程序中的最小可测试单元——通常是单个类或方法。通过单元测试,可以确保每个模块按预期工作,从而提高代码的质量和可靠性。 2.安装和配…...
深度学习 Pytorch 深层神经网络
在之前已经学习了三种单层神经网络,分别为实现线性方程的回归网络,实现二分类的逻辑回归(二分类网络),以及实现多分类的softmax回归(多分类网络)。从本节开始,我们将从单层神经网络展…...
【python】三帧差法实现运动目标检测
三帧差法是一种常用的运动目标检测方法,它通过比较连续三帧图像之间的差异来检测运动物体。这种方法尤其适用于背景变化较小的场景。 目录 1 方案 2 实践 ① 代码 ② 效果图 1 方案 具体步骤如下: ① 读取视频流:使用cv2.VideoCapture()…...
机器人抓取与操作经典规划算法(深蓝)——2
1 经典规划算法 位姿估计:(1)相机系位姿 (2)机器人系位姿 抓取位姿:(1)抓取位姿计算 (2)抓取评估和优化 路径规划:(1)笛卡…...
WGCLOUD服务器资源监控软件使用笔记 - Token is error是什么错误
[wgcloud-agent]2025/01/30 10:41:30 WgcloudAgent.go:90: 主机监控信息上报server开始 [wgcloud-agent]2025/01/30 10:41:30 WgcloudAgent.go:99: 主机监控信息上报server返回信息: {"result":"Token is error"} 这个错误是因为agent配置的wgToken和serv…...
在排序数组中查找元素的第一个和最后一个位置(力扣)
一.题目介绍 二.题目解析 使用二分进行查找 2.1处理边界情况 如果数组为空,直接返回 [-1, -1],因为无法找到目标值。 int[] ret new int[2]; ret[0] ret[1] -1; if (nums.length 0) return ret; 2.2查找左端点(目标值开始位置&#…...
Kafka的消息协议
引言 在学习MQTT消息协议的时候我常常思考kafka的消息协议是什么,怎么保证消息的可靠性和高性能传输的,接下来我们一同探究一下 Kafka 在不同的使用场景和组件交互中用到了多种协议,以下为你详细介绍: 内部通信协议 Kafka 使用…...
Vue 3 30天精进之旅:Day 09 - 组合式API
在Vue 3中,组合式API(Composition API)是一个引入的新特性,它为开发者提供了一种更灵活的方式来构建和组织组件。与传统的选项API相比,组合式API更注重逻辑的复用和逻辑的组合,让我们更容易处理大型应用中的…...
Day28(补)-【AI思考】-AI会不会考虑自己的需求?
文章目录 AI会不会考虑自己的需求?一、**技术本质:深度≠理解**二、**传播机制:热搜如何制造幻觉**三、**伦理考量:为何必须"撇清"**关键结论 AI会不会考虑自己的需求? 让思想碎片重焕生机的灵魂:…...
JavaScript 进阶(下)
原型 what 首先,构造函数通过原型分配的函数是所有对象所 共享的。 然后,JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象,所以我们也称为原型对象 这个对象可以挂载函数,对象实…...
selenium自动化测试框架——面试题整理
目录 1. 什么是 Selenium?它的工作原理是什么? 2. Selenium 主要组件 3. 常见 WebDriver 驱动 4. Selenium 如何驱动浏览器? 5. WebDriver 协议是什么? 6. Page Object 模式与 Page Factory 7. 如何判断元素是否可见&#x…...
CF1098F Ж-function
【题意】 给你一个字符串 s s s,每次询问给你 l , r l, r l,r,让你输出 s s s l , r sss_{l,r} sssl,r中 ∑ i 1 r − l 1 L C P ( s s i , s s 1 ) \sum_{i1}^{r-l1}LCP(ss_i,ss_1) ∑i1r−l1LCP(ssi,ss1)。 【思路】 和前一道题一样&#…...
数据库备份、主从、集群等配置
数据库备份、主从、集群等配置 1 MySQL1.1 docker安装MySQL1.2 主从复制1.2.1 主节点配置1.2.2 从节点配置1.2.3 创建用于主从同步的用户1.2.4 开启主从同步1.2.4 主从同步验证 1.3 主从切换1.3.1 主节点设置只读(在192.168.1.151上操作)1.3.2 检查主从数…...
电脑要使用cuda需要进行什么配置
在电脑上使用CUDA(NVIDIA的并行计算平台和API),需要进行以下配置和准备: 1. 检查NVIDIA显卡支持 确保你的电脑拥有支持CUDA的NVIDIA显卡。 可以在NVIDIA官方CUDA支持显卡列表中查看显卡型号是否支持CUDA。 2. 安装NVIDIA显卡驱动…...
【Unity3D】实现横版2D游戏——攀爬绳索(简易版)
目录 GeneRope.cs 场景绳索生成类 HeroColliderController.cs 控制角色与单向平台是否忽略碰撞 HeroClampController.cs 控制角色攀爬 OnTriggerEnter2D方法 OnTriggerStay2D方法 OnTriggerExit2D方法 Update方法 开始攀爬 结束攀爬 Sensor_HeroKnight.cs 角色触发器…...
JS 时间格式大全(含大量示例)
在 JS 中,处理时间和日期是常见的需求。无论是展示当前时间、格式化日期字符串,还是进行时间计算,JavaScript 都提供了丰富的 API 来满足这些需求。本文将详细介绍如何使用 JavaScript 生成各种时间格式,从基础到高级,…...
opencv裁剪视频区域
import cv2 # 打开视频文件 video_path input.mp4 cap cv2.VideoCapture(video_path) # 获取视频的帧率、宽度和高度 fps int(cap.get(cv2.CAP_PROP_FPS)) width int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # 定义裁剪区…...
C++ deque(1)
1.deque介绍 deque的扩容不像vector那样麻烦 直接新开一个buffer 不用重新开空间再把数据全部移过去 deque本质上是一个指针数组和vector<vector>不一样,vector<vector>本质上是一个vector对象数组!并且vector<vector>的buffer是不一…...
MapReduce概述
目录 1. MapReduce概述2. MapReduce的功能2.1 数据划分和计算任务调度2.2 数据/代码互定位2.3 系统优化2.4 出错检测和恢复 3. MapReduce处理流程4. MapReduce编程基础参考 1. MapReduce概述 MapReduce是面向大数据并行处理的计算模型、框架和平台: 1. 基于集群的高性能并行…...
DOM操作中childNodes与children的差异及封装方案
引言 在JavaScript的DOM操作中,childNodes和children是开发者常用的属性,但它们在浏览器中的行为差异可能导致兼容性问题。尤其是在处理空白符(如换行符\n)时,某些浏览器(如Chrome和Edge)会将空…...
在线课堂小程序设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
分布式系统架构怎么搭建?
分布式系统架构 互联网企业的业务飞速发展,促使系统架构不断变化。总体来说,系统架构大致经历了单体应用架构—垂直应用架构—分布式架构—SOA架构—微服务架构的演变,很多互联网企业的系统架构已经向服务化网格(Service Mesh&am…...
大模型知识蒸馏技术(2)——蒸馏技术发展简史
版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl2006年模型压缩研究 知识蒸馏的早期思想可以追溯到2006年,当时Geoffrey Hinton等人在模型压缩领域进行了开创性研究。尽管当时深度学习尚未像今天这样广泛普及,但Hinton的研究已经为知识迁移和模…...
C++初阶 -- 泛型编程(函数模板、类模板)入门
目录 一、泛型编程 1.1 介绍 二、函数模板 2.1 函数模板的概念 2.2 函数模板的格式 2.3 函数模板的原理 2.4 函数模板的实例化 2.4.1 隐式实例化 2.4.2 显式实例化 2.5 模板参数的匹配原则 三、类模板 3.1 类模板的使用格式 3.2 类模板的实例化 一、泛型编程 在有…...
[EAI-027] RDT-1B: a Diffusion Foundation Model for Bimanual Manipulation
Paper Card 论文标题:RDT-1B: a Diffusion Foundation Model for Bimanual Manipulation 论文作者:Songming Liu, Lingxuan Wu, Bangguo Li, Hengkai Tan, Huayu Chen, Zhengyi Wang, Ke Xu, Hang Su, Jun Zhu 论文链接:https://arxiv.org/ab…...
MongoDB常见的运维工具总结介绍
MongoDB 提供了一些强大的运维工具,帮助管理员进行数据库监控、备份、恢复、性能优化等操作。以下是一些常见的 MongoDB 运维工具及其功能介绍: 1. MongoDB Atlas 功能:MongoDB Atlas 是 MongoDB 官方的云托管数据库服务,它提供…...
dify实现原理分析-rag-数据检索的实现
数据检索的总体执行步骤 数据检索总体步骤如下: #mermaid-svg-YCRNdSE7T1d0Etyj {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-YCRNdSE7T1d0Etyj .error-icon{fill:#552222;}#mermaid-svg-YCRNdSE7T1d…...
20个整流电路及仿真实验汇总
0、 前言 以下是关于“20个整流电路及仿真实验汇总”的前言部分: 在现代电力电子技术领域,整流电路作为将交流电(AC)转换为直流电(DC)的关键电路,广泛应用于各类电源设计、信号处理以及电力电子设备中。整流电路不仅能够为电子设备提供稳定的直流电源,还在电力传输、…...
CVE-2020-0796永恒之蓝2.0(漏洞复现)
目录 前言 产生原因 影响范围 漏洞复现 复现环境 复现步骤 防御措施 总结 前言 在网络安全的战场上,漏洞一直是攻防双方关注的焦点。CVE-2020-0796,这个被称为 “永恒之蓝 2.0” 的漏洞,一度引起了广泛的关注与担忧。它究竟是怎样的…...
爬虫基础(一)HTTP协议 :请求与响应
前言 爬虫需要基础知识,HTTP协议只是个开始,除此之外还有很多,我们慢慢来记录。 今天的HTTP协议,会有助于我们更好的了解网络。 一、什么是HTTP协议 (1)定义 HTTP(超文本传输协议ÿ…...
拼车(1094)
1094. 拼车 - 力扣(LeetCode) 解法: class Solution { public:bool carPooling(vector<vector<int>>& trips, int capacity) {uint32_t passenger_cnt 0;//将原数据按照from排序auto func_0 [](vector<int> & …...
Ubuntu全面卸载mysql
如果你已经看到whereis mysql输出了与MySQL相关的路径,说明MySQL仍然存在于系统中。要卸载MySQL,可以按照以下步骤操作,确保完全删除所有相关的文件和配置: 1. 停止MySQL服务 首先,停止MySQL服务: sudo …...
@Inject @Qualifier @Named
Inject Qualifier Named 在依赖注入(DI)中,Inject、Qualifier 和 Named 是用于管理对象创建和绑定的关键注解。以下是它们的用途、依赖配置和代码示例的详细说明: 1. 注解的作用 Inject:标记需要注入的构造函数、字段…...
OpenHarmonyOS 3.2 编译生成的hap和app文件的名称如何配置追加版本号?
找了一圈发现官方的文档都是最新的,3.2很多API都不支持,比如获取OhosAppContext,通过OhosAppContext来获取应用版本号,最终是通过读取app.json5的文件内容来读取版本号,最终修改entry下的hvigorfile.ts如下,…...
初始化mysql报错cannot open shared object file: No such file or directory
报错展示 我在初始化msyql的时候报错:mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory 解读: libaio包的作用是为了支持同步I/O。对于数据库之类的系统特别重要,因此…...
Vue.js组件开发-实现全屏背景图片滑动切换特效
使用 Vue 实现全屏背景图片滑动切换特效的详细步骤、代码、注释和使用说明。 步骤 创建 Vue 项目:使用 Vue CLI 创建一个新的 Vue 项目。准备图片资源:准备好要用于背景切换的图片,并将它们放在项目的合适目录下。编写 HTML 结构࿱…...
AI在自动化测试中的伦理挑战
在软件测试领域,人工智能(AI)已经不再是遥不可及的未来技术,而是正在深刻影响着测试过程的现实力量。尤其是在自动化测试领域,AI通过加速测试脚本生成、自动化缺陷检测、测试数据生成等功能,极大提升了测试…...
FreeRTOS的任务创建和删除
1,任务创建和删除的API函数 任务的创建和删除本质就是调用FreeRTOS的API函数 动态创建任务: 任务的任务控制块以及任务的栈空间所需的内存,均由 FreeRTOS 从 FreeRTOS 管理的堆中分配。 静态创建任务: 任务的任务控制块以及任务的…...
【C++】STL容器使用与实现详解:vector
文章目录 Ⅰ. vector的介绍和使用一、vector的介绍二、vector的使用 (只列出比较重要的,其他的需要时查文档)1. vector的定义2. vector iterator(迭代器)的使用3. vector 容量问题4. vector 增删查改5. 正确释放 vecto…...
【Block总结】动态蛇形卷积,专注于细长和弯曲的局部结构|即插即用
论文信息 标题: Dynamic Snake Convolution based on Topological Geometric Constraints for Tubular Structure Segmentation 作者: 戚耀磊、何宇霆、戚晓明、张媛、杨冠羽 会议: 2023 IEEE/CVF International Conference on Computer Vision (ICCV) 发表时间: 2023年10月…...
物业管理软件引领社区智能化转型提升服务效率与居民生活质量
内容概要 物业管理软件的出现,标志着社区管理方式的一场革命,它不仅仅是一个工具,更是推动智能化转型的关键助力。通过高效的管理功能,物业管理软件在优化服务流程的同时,也提升了居民的生活质量和社区的整体发展活力…...
论文阅读(十三):复杂表型关联的贝叶斯、基于系统的多层次分析:从解释到决策
1.论文链接:Bayesian, Systems-based, Multilevel Analysis of Associations for Complex Phenotypes: from Interpretation to Decision 摘要: 遗传关联研究(GAS)报告的结果相对稀缺,促使许多研究方向。尽管关联概念…...
线性调整器——耗能型调整器
线性调整器又称线性电压调节器,以下是关于它的介绍: 基本工作原理 线性调整器的基本电路如图1.1(a)所示,晶体管Q1(工作于线性状态,或非开关状态)构成一个连接直流源V和输出端V。的可调电气电阻,直流源V由60Hz隔离变压器(电气隔离和整流&#…...
梯度提升用于高效的分类与回归
使用 决策树(Decision Tree) 实现 梯度提升(Gradient Boosting) 主要是模拟 GBDT(Gradient Boosting Decision Trees) 的原理,即: 第一棵树拟合原始数据计算残差(负梯度…...
使用Ollama和Open WebUI快速玩转大模型:简单快捷的尝试各种llm大模型,比如DeepSeek r1
Ollama本身就是非常优秀的大模型管理和推理组件,再使用Open WebUI更加如虎添翼! Ollama快速使用指南 安装Ollama Windows下安装 下载Windows版Ollama软件:Release v0.5.7 ollama/ollama GitHub 下载ollama-windows-amd64.zip这个文件即可…...
2025年1月个人工作生活总结
本文为 2025年1月工作生活总结。 研发编码 使用sqlite3命令行查询表数据 可以直接使用sqlite3查询数据表,不需进入命令行模式。示例如下: sqlite3 database_name.db "SELECT * FROM table_name;"linux shell使用read超时一例 先前有个编译…...
Windows环境安装nvm,并使用nvm管理nodejs版本教程
目录 1.nvm安装步骤 2.验证nvm是否安装成功 3.查看本地可以安装的所有版本 4.安装特定nodejs版本 5.配置nvm镜像 6.使用特定nodejs版本 7.给nodejs配置镜像和环境变量 8.查看本地安装的所有版本(* 表示当前版本) 9.卸载指定版本的nodejs 前端开发中,不…...
C++中常用的排序方法之——冒泡排序
成长路上不孤单😊😊😊😊😊😊 【14后😊///计算机爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于C中常用的排序方法之——冒泡排序的…...