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

【SpringBoot3】面向切面 AspectJ AOP 使用详解

文章目录
    • 一、AspectJ介绍
    • 二、简单使用步骤
      • 1、引入依赖
      • 2、定义一个Aspect
      • 3、开启AOP支持
    • 三、AOP 核心概念
    • 四、切点(Pointcut)
      • 1. execution
      • 2. within
      • 3. this & target
      • 4. args & @args
      • 5. @within & @target & @annotation
    • 五、通知(Advice)
      • 1. @Before 示例:日志记录
      • 2. @AfterReturning 示例:处理返回值
      • 3. @AfterThrowing 示例:异常处理
      • 4. @After 示例:资源释放
      • 5. @Around 示例:方法执行前后处理
      • 6. 参数相关 Advice 示例:验证参数
      • 7. 注解相关 Advice 示例:基于注解的日志记录
      • 8. @AfterThrowing 异常示例:特定异常处理
      • 9. @Pointcut 单独定义切点,其他Advice直接引用
    • 参考

一、AspectJ介绍

AspectJ是一个面向切面的框架,它扩展了Java语言,并定义了AOP(面向切面编程)语法。

AspectJ支持数据埋点、日志记录、性能统计、安全控制、事务处理、异常处理等多种横切关注点。通过AspectJ,开发者可以更加直观地定义和理解代码的行为,减少对业务逻辑的干扰。

  • 特点
  1. 模块化:AspectJ允许开发者将横切关注点以模块化的方式进行管理和重用,提高了代码的可维护性和可读性。
  2. 声明式编程:AspectJ使用注解或XML配置的方式来声明横切关注点,减少了重复的样板代码。
  3. 细粒度控制:AspectJ提供了丰富的切点表达式语言,可以精确地选择需要横切的连接点,实现对代码的细粒度控制。
  4. 跨模块切面:AspectJ可以在不同的模块之间进行切面的织入,使得横切关注点可以跨越多个模块进行统一管理。
  5. 与Java语言的兼容性:AspectJ是基于Java语言的扩展,与Java语法完全兼容,可以无缝地与现有的Java代码进行集成和使用。

二、简单使用步骤

1、引入依赖
<dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-aop</artifactId>  
</dependency>
2、定义一个Aspect
import org.aspectj.lang.annotation.Aspect;  
import org.aspectj.lang.annotation.Before;  
import org.springframework.stereotype.Component;  @Aspect  
@Component  
public class MyAspect {  // 定义切点,表示对哪些类的哪些方法进行拦截  // execution表达式指定了方法签名  // 第一个"*"表示任意返回类型,第二个"*"表示类中的任意方法  // ".."表示任意参数  // 这里的例子表示拦截UserService中的所有方法  @Before("execution(* com.example.service.UserService.*(..))")  public void beforeAdvice() {  System.out.println("Before method: Do something before.");  }  
}
3、开启AOP支持

在Spring Boot应用中,通常通过@SpringBootApplication注解启动应用,该注解包含了@EnableAspectJAutoProxy,因此默认情况下Spring Boot应用是支持AOP的。

如果你的应用配置较为特殊,确保你的配置类上(通常是主类)添加了@EnableAspectJAutoProxy注解以开启对AspectJ自动代理的支持。

三、AOP 核心概念

  • 切面(Aspect):AOP 的模块单元,封装了切点、通知以及类型间声明。在Spring AOP中,切面通过使用常规类或使用@Aspect注解的常规类(@AspectJ风格)来实现。

  • 连接点(Join point):程序流中指定的一点,如方法调用、方法执行、字段访问等。

  • 通知(Advice):切面在特定连接点上采取的动作。通知包括“环绕”、“前置”和“后置”通知。许多AOP框架,包括Spring,都将通知建模为拦截器,并在连接点周围维护一个拦截器链。

  • 切点(Pointcut):匹配连接点的谓词。通知与切点表达式相关联。Spring默认使用AspectJ切点表达式语言。

  • 引入(Introduction):代表一个类型声明额外的方法或字段。Spring AOP允许您向任何被通知的对象引入新接口(以及相应的实现)。例如,您可以使用引入来使bean实现IsModified接口,以简化缓存。

  • 目标对象(Target object):被一个或多个切面通知的对象。也称为“被通知对象”。由于Spring AOP是通过使用运行时代理实现的,因此这个对象总是一个代理对象。

  • AOP代理(AOP proxy):由AOP框架创建的对象,用于实现切面契约(如通知方法的执行等)。在Spring框架中,AOP代理是JDK动态代理或CGLIB代理。

  • 织入(Weaving):将切面与其他应用类型或对象链接起来以创建被通知对象。这可以在编译时(例如,使用AspectJ编译器)、加载时或运行时完成。Spring AOP像其他纯Java AOP框架一样,在运行时执行织入。

Spring AOP包括以下类型的通知:

  • 前置通知(Before advice):在连接点之前运行的通知,但它没有能力阻止执行程序执行(除非它抛出异常)。
  • 后置返回通知(After returning advice):在连接点正常完成后运行的通知(例如,如果方法返回而没有抛出异常)。
  • 后置异常通知(After throwing advice):如果方法通过抛出异常退出时运行的通知。
  • 后置(最终)通知(After (finally) advice):无论连接点以何种方式退出(正常或异常返回)都要运行的通知。
  • 环绕通知(Around advice):围绕连接点(如方法调用)的通知。这是最强大的通知类型。环绕通知可以在方法调用之前和之后执行自定义行为。它还负责选择是否继续到连接点,或者通过返回自己的返回值或抛出异常来短路被通知方法的执行。

环绕通知是最通用的通知类型。由于Spring AOP像AspectJ一样提供了全范围的通知类型,因此建议您使用能够实现所需行为的最不强大的通知类型。例如,如果您只需要使用方法的返回值更新缓存,那么实现后置返回通知比实现环绕通知更好,尽管环绕通知也可以完成同样的事情。使用最具体的通知类型提供了更简单的编程模型,并且减少了出错的可能性。例如,您不需要在用于环绕通知的JoinPoint上调用proceed()方法,因此您不会忘记调用它。

所有通知参数都是静态类型的,因此您可以使用适当类型的通知参数(例如,方法执行的返回值的类型)而不是Object数组。

四、切点(Pointcut)

Spring AOP支持使用AspectJ切入点表达式来指定切点。这些表达式可以非常灵活地定义需要拦截的方法集合。以下是一些常用的切点指示符和示例:

1. execution

execution是最常用的切入点指示符,用于匹配方法执行的连接点。其语法结构如下:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
  • modifiers-pattern(可选):方法的修饰符,如publicprivate等。
  • ret-type-pattern:方法的返回类型,*表示任意类型。
  • declaring-type-pattern(可选):声明方法的类,支持使用..来表示包及其子包下的所有类。
  • name-pattern:方法的名称。
  • param-pattern:方法的参数列表,..表示任意数量和类型的参数,*表示任意类型的一个参数,(*, String)表示第一个参数是任意类型,第二个参数是String类型。
  • throws-pattern(可选):方法抛出的异常类型。

示例

  • 匹配任意类的任意方法:execution(* *(..))
  • 匹配com.example.service包下所有类的所有方法:execution(* com.example.service..*.*(..))
  • 匹配MyService类中的doSomething方法:execution(* com.example.service.MyService.doSomething(..))
  • 匹配任意类的save方法,且方法参数为java.lang.String类型:execution(* *.save(java.lang.String))
2. within

within用于匹配指定类型内的方法执行,包括指定的接口、类或包。

示例

  • 匹配com.example.dao包下的所有类的所有方法:within(com.example.dao.*)
  • 匹配com.example.dao包及其子包中所有类中的所有方法:within(com.example.dao..*)
  • 匹配实现了UserService接口的类的所有方法:within(com.example.service.UserService+)
3. this & target
  • this:用于匹配当前AOP代理对象类型的执行方法,注意是AOP代理对象的类型匹配。
  • target:用于匹配当前目标对象类型的执行方法,注意是目标对象的类型匹配。

示例

  • 匹配当前AOP代理对象类型为MyService的所有方法执行:this(com.example.service.MyService)
  • 匹配当前目标对象类型为MyService的所有方法执行:target(com.example.service.MyService)
4. args & @args
  • args:用于匹配当前执行的方法传入的参数为指定类型的执行方法,参数类型列表中的参数必须是类型全限定名,通配符不支持。
  • @args:匹配方法传入的参数所属类上拥有指定的注解的情况。

示例

  • 匹配方法参数为String类型的方法:args(java.lang.String)
  • 匹配方法参数类型上拥有@MyAnnotation注解的方法调用:@args(com.example.MyAnnotation)
5. @within & @target & @annotation
  • @within:匹配类级别上应用了特定注解的类中的所有方法。
  • @target:匹配运行时目标对象(代理对象)的类型上应用了特定注解的方法(在Spring AOP中常用于代理对象的切点定义)。
  • @annotation:匹配方法级别上应用了特定注解的方法。

示例

  • 匹配所有类上具体指定了@MyAnnotation注解的类内的所有方法:@within(com.example.MyAnnotation)
  • 匹配当前目标对象类型持有@MyAnnotation注解的方法:@target(com.example.MyAnnotation)
  • 匹配所有拥有@MyAnnotation注解的外部调用方法:@annotation(com.example.MyAnnotation)

五、通知(Advice)

Spring AOP提供了多种类型的Advice,包括:

  1. @Before:在目标方法执行之前执行。
  2. @AfterReturning:在目标方法正常执行完成后执行。
  3. @AfterThrowing:在目标方法抛出异常时执行。
  4. @After:无论目标方法执行结果如何,最终都会执行。
  5. @Around:在目标方法执行前后执行,并可以控制目标方法的执行。

每种类型的Advice都需要与切入点表达式结合使用,以确定其应用的范围。

1. @Before 示例:日志记录

在方法执行之前记录日志,常用于跟踪方法的调用。

@Aspect
@Component
public class LoggingAspect {// 定义切点,表示对哪些类的哪些方法进行拦截// execution表达式指定了方法签名// 第一个"*"表示任意返回类型,第二个"*"表示类中的任意方法// ".."表示任意参数// 这里的例子表示拦截UserService中的所有方法@Before("execution(* com.example.service.UserService.*(..))")public void logBeforeMethodExecution(JoinPoint joinPoint) {System.out.println("Before executing method: " + joinPoint.getSignature().getName());}// 定义切点,表示对哪些类的哪些方法进行拦截// execution表达式指定了方法签名// 第一个"*"表示任意返回类型,第二个"*"表示类中的任意方法// 第一次".."表示包及其子包下的所有类// 第二次".."表示任意参数@Before("execution(* com.example..*(..))")public void logBeforeMethodExecutionAll(JoinPoint joinPoint) {System.out.println("Before executing method all: " + joinPoint.getSignature().getName());}
}
2. @AfterReturning 示例:处理返回值

在方法成功执行并返回后,对返回值进行处理或记录。

@Aspect
@Component
public class ReturnValueAspect {@AfterReturning(pointcut = "execution(* com.example.service.UserService.getUserById(..))", returning = "result")public void logReturnValue(Object result) {System.out.println("Method returned: " + result);}
}
3. @AfterThrowing 示例:异常处理

在方法抛出异常时捕获异常,并进行相应的处理或记录。

@Aspect
@Component
public class ExceptionHandlingAspect {@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "ex")public void handleException(Exception ex) {System.err.println("An exception occurred: " + ex.getMessage());}
}
4. @After 示例:资源释放

无论方法执行结果如何,都会在方法执行后执行,常用于资源释放。

@Aspect
@Component
public class ResourceReleaseAspect {@After("execution(* com.example.service.*.*(..))")public void releaseResources() {System.out.println("Resources are released after method execution");}
}
5. @Around 示例:方法执行前后处理

在方法执行前后都进行处理,可以控制方法的执行或添加额外的逻辑。

@Aspect
@Component
public class AroundAdviceAspect {@Around("execution(* com.example.service.UserService.*(..))")public Object logAroundMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("Before executing method: " + joinPoint.getSignature().getName());Object result = joinPoint.proceed(); // 执行目标方法System.out.println("After executing method: " + joinPoint.getSignature().getName());return result;}
}
6. 参数相关 Advice 示例:验证参数

在方法执行之前验证参数的有效性。

@Aspect
@Component
public class ParameterValidationAspect {@Before("execution(* com.example.service.UserService.addUser(com.example.model.User)) && args(user)")public void validateUserParameter(User user) {if (user == null || user.getName() == null || user.getName().isEmpty()) {throw new IllegalArgumentException("User parameter is invalid");}}
}
7. 注解相关 Advice 示例:基于注解的日志记录

根据方法上的注解来决定是否进行日志记录。可以使用注解全限定名或使用参数中的注解参数名。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Loggable {
}@Aspect
@Component
public class AnnotationDrivenLoggingAspect {@Before("@annotation(com.example.aspect.Loggable)")public void logMethodWithAnnotation(JoinPoint joinPoint) {System.out.println("Executing loggable method: " + joinPoint.getSignature().getName());}// 使用参数中的注解@Before("@annotation(loggable)")public void logMethodWithAnnotationArg(JoinPoint joinPoint, Loggable loggable) {System.out.println("Executing loggable method: " + joinPoint.getSignature().getName());}
}// 在需要日志记录的方法上使用@Loggable注解
@Service
public class MyService {@Loggablepublic void myLoggableMethod() {// ...}
}
8. @AfterThrowing 异常示例:特定异常处理

仅当方法抛出特定类型的异常时进行处理。

@Aspect
@Component
public class SpecificExceptionHandlingAspect {@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "ex")public void handleSpecificException(CustomException ex) {System.err.println("A CustomException occurred: " + ex.getMessage());}
}// 自定义异常类
public class CustomException extends RuntimeException {public CustomException(String message) {super(message);}
}
9. @Pointcut 单独定义切点,其他Advice直接引用
@Aspect
@Component
public class LoggingAspect {// 定义切点,表示对哪些类的哪些方法进行拦截// execution表达式指定了方法签名// 第一个"*"表示任意返回类型,第二个"*"表示类中的任意方法// ".."表示任意参数// 这里的例子表示拦截UserService中的所有方法@Pointcut("execution(* com.example.service.UserService.*(..))")private void service() {}@Before("service()")public void logBeforeMethodExecution(JoinPoint joinPoint) {System.out.println("Before executing method: " + joinPoint.getSignature().getName());}}

参考

  • https://docs.spring.io/spring-framework/reference/core/aop.html

相关文章:

【SpringBoot3】面向切面 AspectJ AOP 使用详解

文章目录 一、AspectJ介绍二、简单使用步骤 1、引入依赖2、定义一个Aspect3、开启AOP支持 三、AOP 核心概念四、切点&#xff08;Pointcut&#xff09; 1. execution2. within3. this & target4. args & args5. within & target & annotation 五、通知&#xf…...

容器运行常见数据库

一.涉及镜像压缩包 均为amd架构版本&#xff1a;mysql:5.7.42、postgres:13.16、dm8:20250206_rev257733_x86_rh6_64、oceanbase-ce:v4.0、opengauss:5.0.2 通过网盘分享的文件&#xff1a;db.tgz 链接: https://pan.baidu.com/s/1EBbFPZj1FxCA4_GxjVunWg?pwd563s 提取码: 5…...

OpenGL ES学习大纲

如果您想从头学习 OpenGL ES,以下是一个详细的学习大纲,涵盖了从基础到高级的知识点,循序渐进地帮助您掌握 OpenGL ES 的核心概念、API 使用、渲染管线、着色器编程、性能优化等内容。 1. 学习前的准备 1.1 基础知识 在学习 OpenGL ES 之前,您需要掌握以下基础知识: 数学…...

Kotlin 优雅的接口实现

1. 日常遇到的冗余的接口方法实现 日常开发中&#xff0c;经常会要实现接口&#xff0c;但是很多场景中&#xff0c;只需要用到其中一两个方法&#xff0c;例如 ActivityLifecycleCallbacks&#xff0c;它有很多个接口需要实现&#xff0c;但是很多时候我们只需要用到其中的一…...

数据结构实现顺序表的尾插,尾删,按值查找/修改/删除,按下标查找/增加/删除

头文件&#xff1a;head.h #ifndef __HEAD_H__ #define __HEAD_H__#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAXSIZE 20enum num {success,false-1};typedef int datatype;typedef struct {int len;datatype data[MAXSIZE]; }S…...

qt实现文字跑马灯效果

实现跑马灯的方式多种多少样&#xff0c;可以通过定时器&#xff0c;或者animation等来实现。 本文通过定时器&#xff0c;将第一个文字&#xff0c;移动到最后一个这种方式来实现&#xff0c;还有其他方式哈。 直接上源码 h文件 #ifndef TEXTTICKER_H #define TEXTTICKER_…...

PyTorch Tensor 形状变化操作详解

PyTorch Tensor 形状变化操作详解 在深度学习中&#xff0c;Tensor 的形状变换是非常常见的操作。PyTorch 提供了丰富的 API 来帮助我们调整 Tensor 的形状&#xff0c;以满足模型输入、计算或数据处理的需求。本文将详细介绍 PyTorch 中常见的 Tensor 形状变换操作&#xff0…...

关于Node.js前端面试的试题概念、工作原理及实际应用

文章目录 1. 什么是Node.js&#xff1f;2. Node.js是如何工作的&#xff1f;3. Node.js与其他流行的框架相比有何优势&#xff1f;4. Node.js如何克服I/O操作阻塞的问题&#xff1f;5. 为什么Node.js是单线程的&#xff1f;6. 如果Node.js是单线程的&#xff0c;那么它是如何处…...

OpenCV机器学习(3)期望最大化(Expectation-Maximization, EM)算法cv::ml::EM

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::ml::EM 是 OpenCV 机器学习模块中的一部分&#xff0c;用于实现期望最大化&#xff08;Expectation-Maximization, EM&#xff09;算法。EM …...

Spring Boot 集成 Kettle

Kettle 简介 Kettle 最初由 Matt Casters 开发&#xff0c;是 Pentaho 数据集成平台的一部分。它提供了一个用户友好的界面和丰富的功能集&#xff0c;使用户能够轻松地设计、执行和监控 ETL 任务。Kettle 通过其强大的功能和灵活性&#xff0c;帮助企业高效地处理大规模数据集…...

Debezium同步之如何同步GIS数据

Debezium 可以用于同步数据库中的变更数据(CDC),包括GIS(地理信息系统)数据。GIS 数据通常存储在具有地理空间数据类型的表中,例如 PostGIS(PostgreSQL 的扩展)中的 geometry 或 geography 类型。通过 Debezium,可以实时捕获和同步这类数据的变更。本文章简单介绍Post…...

Java与C语言中取模运算符%的区别对比

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: Java 文章目录 &#x1f4af;前言&#x1f4af;C语言中的取模运算符 %基本行为示例 注意事项示例&#xff1a;负数取模 &#x1f4af;Java中的取模运算符 %基本行为示例 对浮点数的支持示例&#xff1a;浮点数取模 符…...

如何commit后更新.gitignore实现push

目录 步骤 1: 更新 .gitignore 文件 步骤 2: 移除已追踪的大文件 步骤 3: 提交更改 步骤 4: 尝试推送 注意事项 如果已经执行了git commit&#xff0c;但后来意识到需要更新.gitignore文件以排除某些不应该被追踪的大文件或目录&#xff0c;并希望在不丢失现有提交记录的情…...

从MySQL迁移到PostgreSQL的完整指南

1.引言 在现代数据库管理中&#xff0c;选择合适的数据库系统对业务的成功至关重要。随着企业数据量的增长和对性能要求的提高&#xff0c;许多公司开始考虑从MySQL迁移到PostgreSQL。这一迁移的主要原因包括以下几个方面&#xff1a; 1.1 性能和扩展性 PostgreSQL以其高性能…...

20250214 随笔 Nginx 负载均衡在数据库中的应用

Nginx 负载均衡在数据库中的应用 在高并发环境下&#xff0c;数据库的性能往往是系统的瓶颈。为了提高数据库的吞吐能力、优化请求分配、减少单点故障&#xff0c;我们可以使用 Nginx 负载均衡 来优化数据库的访问。本文将介绍如何使用 Nginx 进行数据库负载均衡&#xff0c;以…...

从养殖场到科技前沿:YOLOv11+OpenCV精准计数鸡蛋与鸡

前言 谁能想到,鸡蛋和鸡的计数居然能变成一项高科技活儿?想象一下,早上去市场,卖家把鸡蛋摔得稀巴烂,结果鸡蛋滚得到处都是——难道你就得一个个捡回来数?还得小心别弄错?可是,你又不是超人!别担心,科技来帮忙!今天的主角是YOLOv11和OpenCV,它们是计算机视觉领域的…...

【Qt】 Data Visualization

三维数据可视化 三维柱状图三维图的创建程序截图示例代码 三维散点图三维图创建程序截图示例代码 三维曲面图三维图创建程序截图示例代码 Data Visualization 是 Qt 中的一个三维数据可视化模块&#xff0c;可用于绘制三维柱状图、三维散点图和三维曲面。与 Charts 模块类似&am…...

python基础语法

文章目录 字面量定义分类 注释定义分类单行注释多行注释 变量定义 数据类型类型转换定义 案例 标识符定义命名规则内容限定大小写敏感不可使用关键字 命名规范变量的命名规范 运算符数学运算符赋值运算符复合赋值运算符 定义字符串定义方式 字符串拼接语法 字符串格式化语法1字…...

【C++游戏开发-五子棋】

使用C开发五子棋游戏的详细实现方案&#xff0c;涵盖核心逻辑、界面设计和AI对战功能&#xff1a; 1. 项目结构 FiveChess/ ├── include/ │ ├── Board.h // 棋盘类 │ ├── Player.h // 玩家类 │ ├── AI.h // AI类 │ └── Game.h // 游戏主逻辑 ├── src/ …...

C/C++ | 每日一练 (2)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 C/C | 每日一练 (2)题目参考答案封装继承多态虚函数底…...

如何在 VS Code 中快速使用 Copilot 来辅助开发

在日常开发中&#xff0c;编写代码往往是最耗时的环节之一。而 GitHub Copilot&#xff0c;作为一款 AI 编码助手&#xff0c;可以帮助开发者 自动补全代码、生成代码片段&#xff0c;甚至直接编写完整的函数&#xff0c;大幅提升编码效率。那么&#xff0c;如何在 VS Code 中快…...

FFmpeg源码:av_strlcpy函数分析

一、引言 在C/C编程中经常会用到strcpy这个字符串复制函数。strcpy是C/C中的一个标准函数&#xff0c;可以把含有\0结束符的字符串复制到另一个地址空间。但是strcpy不会检查目标数组dst的大小是否足以容纳源字符串src&#xff0c;如果目标数组太小&#xff0c;将会导致缓冲区…...

【生产变更】- 集群中配置SCAN ip的不同端口应用

【生产变更】- 集群中配置SCAN ip的不同端口应用 一、概述二、操作步骤三、故障解决 一、概述 使用非默认端口&#xff08;1521&#xff09;监听scan ip。 二、操作步骤 1、添加11521端口 srvctl add listener -l lis11521 -o /opt/grid/products/11.2.0 -p 11521 srvctl st…...

RabbitMQ 3.12.2:单节点与集群部署实战指南

前言&#xff1a;在当今的分布式系统架构中&#xff0c;消息队列已经成为不可或缺的组件之一。它不仅能够实现服务之间的解耦&#xff0c;还能有效提升系统的可扩展性和可靠性。RabbitMQ 作为一款功能强大且广泛使用的开源消息中间件&#xff0c;凭借其高可用性、灵活的路由策略…...

Node.js技术原理分析系列——如何在Node.js中新增一个内置模块

本文由体验技术团队曹杨毅原创。 Node.js 是一个开源的、跨平台的JavaScript运行时环境&#xff0c;它允许开发者在服务器端运行JavaScript代码。Node.js 是基于Chrome V8引擎构建的&#xff0c;专为高性能、高并发的网络应用而设计&#xff0c;广泛应用于构建服务器端应用程序…...

从低清到4K的魔法:FlashVideo突破高分辨率视频生成计算瓶颈(港大港中文字节)

论文链接&#xff1a;https://arxiv.org/pdf/2502.05179 项目链接&#xff1a;https://github.com/FoundationVision/FlashVideo 亮点直击 提出了 FlashVideo&#xff0c;一种将视频生成解耦为两个目标的方法&#xff1a;提示匹配度和视觉质量。通过在两个阶段分别调整模型规模…...

康耐视CAM-CIC-10MR-10-GC工业相机

康耐视(COGNEX)的工业相机CAM-CIC-10MR-10-GC是CAM-CIC-10MR系列中的一款型号,主要应用于工业自动化检测和高精度视觉系统 基本参数与特性 分辨率与帧率: CAM-CIC-10MR-10-GC属于康耐视CIC系列,具备10MP(1000万像素)的分辨能力,帧率为10fps。该系列相机支持卷帘快门(R…...

解惑Python:一文解决osgeo库安装失败问题

Osgeo&#xff08;Open Source Geospatial Foundation&#xff09;是一个支持开源地理空间数据处理的基金会&#xff0c;我们可以在python中使用“osgeo”库来访问其提供的高效地理空间数据。例如&#xff0c;我们使用该模块提供的GDAL处理栅格数据&#xff0c;使用OGR处理矢量…...

3、树莓派5 安装VNC查看器 开启VNC服务器

在前序文章中&#xff08; 2、树莓派5第一次开机&#xff09;&#xff0c;可以使用三种方式开机&#xff0c;其中使用网线及wifi的方式均需要使用到VNC查看器进行远程桌面控制&#xff0c;本文将介绍如何下载安装并配置及使用VNC查看器及服务器&#xff0c;对前序文章做一些补充…...

Django 创建表时 “__str__ ”方法的使用

在 Django 模型中&#xff0c;__str__ 方法是一个 Python 特殊方法&#xff08;也称为“魔术方法”&#xff09;&#xff0c;用于定义对象的字符串表示形式。它的作用是控制当对象被转换为字符串时&#xff0c;应该返回什么样的内容。 示例&#xff1a; 我在初学ModelForm时尝…...

STM32 CAN过滤器配置和应用方法介绍

目录 概述 一、CAN过滤器核心概念 二、过滤器配置步骤&#xff08;以标准ID为例&#xff09; 三、不同模式的配置示例 四、高级配置技巧 五、调试与问题排查 六、关键计算公式 总结 概述 在STM32微控制器中&#xff0c;CAN过滤器可以配置为标识符屏蔽模式和标识符列表模…...

【第1章:深度学习概览——1.3 深度学习的核心组件与概念解析之神经网络基础】

大家好!今天咱们一头扎进深度学习的神秘领域,好好探索一下其最重要的基石 —— 神经网络。不管你是深度学习的新手小白,还是已经接触过一些基础概念,这篇文章都能助力你更透彻地理解神经网络的原理和运作机制。咱们从最基础的知识入手,一步步揭开神经网络的神秘面纱! 一、…...

Python中如何进行数据库连接?

在 Python 中进行数据库连接&#xff0c;不同的数据库需要使用不同的库。下面分别介绍几种常见数据库&#xff08;SQLite、MySQL、PostgreSQL&#xff09;的连接方法。 1. 连接 SQLite 数据库 SQLite 是一种轻量级的嵌入式数据库&#xff0c;Python 标准库中自带了sqlite3模块…...

解析 WebGPU 中 device.createBuffer 的参数意义

在 WebGPU 开发里&#xff0c;device.createBuffer 方法扮演着至关重要的角色&#xff0c;它用于创建一个 GPU 缓冲区对象&#xff0c;这个对象能够存储顶点数据、索引数据、统一数据等。下面我们就来详细剖析该方法各个参数的意义。 1. size&#xff1a;决定缓冲区容量 size …...

PLC的集成RAM,存储器卡,用户程序存储空间,数据存储容量分别指的什么,有什么关联?

1. 集成RAM 定义&#xff1a;集成RAM&#xff08;随机存取存储器&#xff09;是PLC内部的高速易失性存储器&#xff0c;用于临时存储运行时的数据&#xff08;如输入/输出状态、中间变量、计数器/定时器的当前值等&#xff09;。 特点&#xff1a; 易失性&#xff1a;断电后数…...

BFS-FloodFill 算法 解决最短路问题 多源 解决拓扑排序

文章目录 一、FloodFill 算法[733. 图像渲染](https://leetcode.cn/problems/flood-fill/description/)2.思路3.代码 [200. 岛屿数量](https://leetcode.cn/problems/number-of-islands/description/)2.思路3.代码 [LCR 105. 岛屿的最大面积](https://leetcode.cn/problems/ZL6…...

USB2.03.0接口区分usb top工具使用

一. USB2.0 & 3.0接口支持区分 1.1. 颜色判断 USB接口的颜色并不是判断版本的可靠标准&#xff0c;但根据行业常见规范分析如下&#xff1a; USB接口颜色与版本对照表&#xff1a; 接口颜色常见版本内部触点数量传输速度黑色USB2.04触点480 Mbps (60 MB/s)白色USB2.0(多…...

2025百度快排技术分析:模拟点击与发包算法的背后原理

一晃做SEO已经15年了&#xff0c;2025年还有人问我如何做百度快速排名&#xff0c;我能给出的答案就是&#xff1a;做好内容的前提下&#xff0c;多刷刷吧&#xff01;百度的SEO排名算法一直是众多SEO从业者研究的重点&#xff0c;模拟算法、点击算法和发包算法是百度快速排名的…...

idea 2019.3常用插件

idea 2019.3常用插件 文档 idea 2019.3常用插件idea 2023.3.7常用插件 idea 2019.3常用插件 插件名称插件版本说明1AceJump3.5.9AceJump允许您快速将插入符号导航到编辑器中可见的任何位置。只需按“ctrl&#xff1b;”&#xff0c;键入一个字符&#xff0c;然后在Ace Jump…...

【Python 学习 / 5】函数详解(定义、参数、作用域、lambda、内置函数)

文章目录 一、函数1. 定义函数1.1 基本函数定义1.2 带参数的函数1.3 带返回值的函数 2. 参数传递2.1 位置参数2.2 默认参数2.3 可变参数2.3.1 使用*args2.3.2 使用**kwargs 2.4 参数的混合使用 3. 作用域3.1 局部和全局变量3.2 global 关键字输出&#xff1a; 3.3 nonlocal关键…...

WPF7-数据绑定基础

1. WPF数据绑定试验 1.1. 数据绑定的核心实现1.2. {Binding}语法1.3. 理解 DataContext 1. WPF数据绑定试验 以下是一个简单的 WPF 数据绑定示例&#xff0c;使用两个TextBox控件分别表示Name和Age来进行进行数据绑定试验。 数据模型类 创建一个 Person 类&#xff0c;包含…...

http 与 https 的区别?

HTTP(超文本传输协议)和 HTTPS(安全超文本传输协议)是互联网通信的基础协议。随着网络技术的发展和安全需求的提升,HTTPS变得越来越重要。本文将深入探讨HTTP与HTTPS之间的区别,包括其工作原理、安全性、性能、应用场景及未来发展等。 1. HTTP与HTTPS的基本概念 1.1 HT…...

大数据学习(49) - Flink按键分区状态(Keyed State)

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 承认自己的无知&#xff0c;乃是开启智慧的大门 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博主哦&#x1f91…...

IP 路由基础 | 路由条目生成 / 路由表内信息获取

注&#xff1a;本文为 “IP 路由” 相关文章合辑。 未整理去重。 IP 路由基础 秦同学学学已于 2022-04-09 18:44:20 修改 一. IP 路由产生背景 我们都知道 IP 地址可以标识网络中的一个节点&#xff0c;并且每个 IP 地址都有自己的网段&#xff0c;各个网段并不相同&#xf…...

COBOL语言的移动应用开发

COBOL语言的移动应用开发探讨 引言 在信息技术快速发展的今天&#xff0c;移动应用开发已成为各行各业不可或缺的一部分。许多企业和开发者纷纷转向使用新兴的编程语言和开发工具&#xff0c;以满足不断变化的用户需求。然而&#xff0c;作为一种历史悠久的编程语言&#xff…...

TCP协议(Transmission Control Protocol)

TCP协议&#xff0c;即传输控制协议&#xff0c;其最大的特征就是对传输的数据进行可靠、高效的控制&#xff0c;其段格式如下&#xff1a; 源端口和目的端口号表示数据从哪个进程来&#xff0c;到哪个进程去&#xff0c;四位报头长度表示的是TCP头部有多少个4字节&#xff0c;…...

C语言数组之二维数组

C语言 主要内容 数组 二维数组 数组 二维数组 定义 二维数组本质上是一个行列式的组合&#xff0c;也就是说二维数组由行和列两部分组成&#xff0c;属于多维数组。二维数组数据是通过行列进行解读。二维数组可被视为一个特殊的一维数组&#xff0c;相当于二维数组又是一…...

计算机专业知识【软件开发中的常用图表:E - R图、HIPO、DFD、N - S、PAD详解】

在软件开发过程中&#xff0c;有许多种图表工具被用于不同阶段的设计和分析&#xff0c;帮助开发者更清晰地理解系统结构、数据流程和算法逻辑。下面将详细介绍E - R图、HIPO图、DFD图、N - S图和PAD图&#xff0c;包括它们的样子和用途。 一、E - R图&#xff08;实体 - 联系…...

多人协同开发 —— Git Aoneflow工作流

一、Aoneflow工作流核心架构 #mermaid-svg-rwTOe9qYwzG3wkdy {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-rwTOe9qYwzG3wkdy .error-icon{fill:#552222;}#mermaid-svg-rwTOe9qYwzG3wkdy .error-text{fill:#552222…...

VSCode运行Go程序报错:Unable to process `evaluate`: debuggee is running

如果使用默认的VSCode的服务器来运行Go程序&#xff0c;那么使用fmt.Scan函数输入数据的时候就会报错&#xff0c;我们需要修改launch.json文件&#xff0c;将Go程序运行在shell终端上。 main.go package mainimport "fmt"func main() {var n intfmt.Scan(&n)v…...