【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,开发者可以更加直观地定义和理解代码的行为,减少对业务逻辑的干扰。
- 特点:
- 模块化:AspectJ允许开发者将横切关注点以模块化的方式进行管理和重用,提高了代码的可维护性和可读性。
- 声明式编程:AspectJ使用注解或XML配置的方式来声明横切关注点,减少了重复的样板代码。
- 细粒度控制:AspectJ提供了丰富的切点表达式语言,可以精确地选择需要横切的连接点,实现对代码的细粒度控制。
- 跨模块切面:AspectJ可以在不同的模块之间进行切面的织入,使得横切关注点可以跨越多个模块进行统一管理。
- 与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(可选):方法的修饰符,如
public
、private
等。 - 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,包括:
- @Before:在目标方法执行之前执行。
- @AfterReturning:在目标方法正常执行完成后执行。
- @AfterThrowing:在目标方法抛出异常时执行。
- @After:无论目标方法执行结果如何,最终都会执行。
- @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 核心概念四、切点(Pointcut) 1. execution2. within3. this & target4. args & args5. within & target & annotation 五、通知…...
容器运行常见数据库
一.涉及镜像压缩包 均为amd架构版本:mysql:5.7.42、postgres:13.16、dm8:20250206_rev257733_x86_rh6_64、oceanbase-ce:v4.0、opengauss:5.0.2 通过网盘分享的文件: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. 日常遇到的冗余的接口方法实现 日常开发中,经常会要实现接口,但是很多场景中,只需要用到其中一两个方法,例如 ActivityLifecycleCallbacks,它有很多个接口需要实现,但是很多时候我们只需要用到其中的一…...
数据结构实现顺序表的尾插,尾删,按值查找/修改/删除,按下标查找/增加/删除
头文件: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实现文字跑马灯效果
实现跑马灯的方式多种多少样,可以通过定时器,或者animation等来实现。 本文通过定时器,将第一个文字,移动到最后一个这种方式来实现,还有其他方式哈。 直接上源码 h文件 #ifndef TEXTTICKER_H #define TEXTTICKER_…...
PyTorch Tensor 形状变化操作详解
PyTorch Tensor 形状变化操作详解 在深度学习中,Tensor 的形状变换是非常常见的操作。PyTorch 提供了丰富的 API 来帮助我们调整 Tensor 的形状,以满足模型输入、计算或数据处理的需求。本文将详细介绍 PyTorch 中常见的 Tensor 形状变换操作࿰…...
关于Node.js前端面试的试题概念、工作原理及实际应用
文章目录 1. 什么是Node.js?2. Node.js是如何工作的?3. Node.js与其他流行的框架相比有何优势?4. Node.js如何克服I/O操作阻塞的问题?5. 为什么Node.js是单线程的?6. 如果Node.js是单线程的,那么它是如何处…...
OpenCV机器学习(3)期望最大化(Expectation-Maximization, EM)算法cv::ml::EM
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::ml::EM 是 OpenCV 机器学习模块中的一部分,用于实现期望最大化(Expectation-Maximization, EM)算法。EM …...
Spring Boot 集成 Kettle
Kettle 简介 Kettle 最初由 Matt Casters 开发,是 Pentaho 数据集成平台的一部分。它提供了一个用户友好的界面和丰富的功能集,使用户能够轻松地设计、执行和监控 ETL 任务。Kettle 通过其强大的功能和灵活性,帮助企业高效地处理大规模数据集…...
Debezium同步之如何同步GIS数据
Debezium 可以用于同步数据库中的变更数据(CDC),包括GIS(地理信息系统)数据。GIS 数据通常存储在具有地理空间数据类型的表中,例如 PostGIS(PostgreSQL 的扩展)中的 geometry 或 geography 类型。通过 Debezium,可以实时捕获和同步这类数据的变更。本文章简单介绍Post…...
Java与C语言中取模运算符%的区别对比
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: Java 文章目录 💯前言💯C语言中的取模运算符 %基本行为示例 注意事项示例:负数取模 💯Java中的取模运算符 %基本行为示例 对浮点数的支持示例:浮点数取模 符…...
如何commit后更新.gitignore实现push
目录 步骤 1: 更新 .gitignore 文件 步骤 2: 移除已追踪的大文件 步骤 3: 提交更改 步骤 4: 尝试推送 注意事项 如果已经执行了git commit,但后来意识到需要更新.gitignore文件以排除某些不应该被追踪的大文件或目录,并希望在不丢失现有提交记录的情…...
从MySQL迁移到PostgreSQL的完整指南
1.引言 在现代数据库管理中,选择合适的数据库系统对业务的成功至关重要。随着企业数据量的增长和对性能要求的提高,许多公司开始考虑从MySQL迁移到PostgreSQL。这一迁移的主要原因包括以下几个方面: 1.1 性能和扩展性 PostgreSQL以其高性能…...
20250214 随笔 Nginx 负载均衡在数据库中的应用
Nginx 负载均衡在数据库中的应用 在高并发环境下,数据库的性能往往是系统的瓶颈。为了提高数据库的吞吐能力、优化请求分配、减少单点故障,我们可以使用 Nginx 负载均衡 来优化数据库的访问。本文将介绍如何使用 Nginx 进行数据库负载均衡,以…...
从养殖场到科技前沿:YOLOv11+OpenCV精准计数鸡蛋与鸡
前言 谁能想到,鸡蛋和鸡的计数居然能变成一项高科技活儿?想象一下,早上去市场,卖家把鸡蛋摔得稀巴烂,结果鸡蛋滚得到处都是——难道你就得一个个捡回来数?还得小心别弄错?可是,你又不是超人!别担心,科技来帮忙!今天的主角是YOLOv11和OpenCV,它们是计算机视觉领域的…...
【Qt】 Data Visualization
三维数据可视化 三维柱状图三维图的创建程序截图示例代码 三维散点图三维图创建程序截图示例代码 三维曲面图三维图创建程序截图示例代码 Data Visualization 是 Qt 中的一个三维数据可视化模块,可用于绘制三维柱状图、三维散点图和三维曲面。与 Charts 模块类似&am…...
python基础语法
文章目录 字面量定义分类 注释定义分类单行注释多行注释 变量定义 数据类型类型转换定义 案例 标识符定义命名规则内容限定大小写敏感不可使用关键字 命名规范变量的命名规范 运算符数学运算符赋值运算符复合赋值运算符 定义字符串定义方式 字符串拼接语法 字符串格式化语法1字…...
【C++游戏开发-五子棋】
使用C开发五子棋游戏的详细实现方案,涵盖核心逻辑、界面设计和AI对战功能: 1. 项目结构 FiveChess/ ├── include/ │ ├── Board.h // 棋盘类 │ ├── Player.h // 玩家类 │ ├── AI.h // AI类 │ └── Game.h // 游戏主逻辑 ├── src/ …...
C/C++ | 每日一练 (2)
💢欢迎来到张胤尘的技术站 💥技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 C/C | 每日一练 (2)题目参考答案封装继承多态虚函数底…...
如何在 VS Code 中快速使用 Copilot 来辅助开发
在日常开发中,编写代码往往是最耗时的环节之一。而 GitHub Copilot,作为一款 AI 编码助手,可以帮助开发者 自动补全代码、生成代码片段,甚至直接编写完整的函数,大幅提升编码效率。那么,如何在 VS Code 中快…...
FFmpeg源码:av_strlcpy函数分析
一、引言 在C/C编程中经常会用到strcpy这个字符串复制函数。strcpy是C/C中的一个标准函数,可以把含有\0结束符的字符串复制到另一个地址空间。但是strcpy不会检查目标数组dst的大小是否足以容纳源字符串src,如果目标数组太小,将会导致缓冲区…...
【生产变更】- 集群中配置SCAN ip的不同端口应用
【生产变更】- 集群中配置SCAN ip的不同端口应用 一、概述二、操作步骤三、故障解决 一、概述 使用非默认端口(1521)监听scan ip。 二、操作步骤 1、添加11521端口 srvctl add listener -l lis11521 -o /opt/grid/products/11.2.0 -p 11521 srvctl st…...
RabbitMQ 3.12.2:单节点与集群部署实战指南
前言:在当今的分布式系统架构中,消息队列已经成为不可或缺的组件之一。它不仅能够实现服务之间的解耦,还能有效提升系统的可扩展性和可靠性。RabbitMQ 作为一款功能强大且广泛使用的开源消息中间件,凭借其高可用性、灵活的路由策略…...
Node.js技术原理分析系列——如何在Node.js中新增一个内置模块
本文由体验技术团队曹杨毅原创。 Node.js 是一个开源的、跨平台的JavaScript运行时环境,它允许开发者在服务器端运行JavaScript代码。Node.js 是基于Chrome V8引擎构建的,专为高性能、高并发的网络应用而设计,广泛应用于构建服务器端应用程序…...
从低清到4K的魔法:FlashVideo突破高分辨率视频生成计算瓶颈(港大港中文字节)
论文链接:https://arxiv.org/pdf/2502.05179 项目链接:https://github.com/FoundationVision/FlashVideo 亮点直击 提出了 FlashVideo,一种将视频生成解耦为两个目标的方法:提示匹配度和视觉质量。通过在两个阶段分别调整模型规模…...
康耐视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(Open Source Geospatial Foundation)是一个支持开源地理空间数据处理的基金会,我们可以在python中使用“osgeo”库来访问其提供的高效地理空间数据。例如,我们使用该模块提供的GDAL处理栅格数据,使用OGR处理矢量…...
3、树莓派5 安装VNC查看器 开启VNC服务器
在前序文章中( 2、树莓派5第一次开机),可以使用三种方式开机,其中使用网线及wifi的方式均需要使用到VNC查看器进行远程桌面控制,本文将介绍如何下载安装并配置及使用VNC查看器及服务器,对前序文章做一些补充…...
Django 创建表时 “__str__ ”方法的使用
在 Django 模型中,__str__ 方法是一个 Python 特殊方法(也称为“魔术方法”),用于定义对象的字符串表示形式。它的作用是控制当对象被转换为字符串时,应该返回什么样的内容。 示例: 我在初学ModelForm时尝…...
STM32 CAN过滤器配置和应用方法介绍
目录 概述 一、CAN过滤器核心概念 二、过滤器配置步骤(以标准ID为例) 三、不同模式的配置示例 四、高级配置技巧 五、调试与问题排查 六、关键计算公式 总结 概述 在STM32微控制器中,CAN过滤器可以配置为标识符屏蔽模式和标识符列表模…...
【第1章:深度学习概览——1.3 深度学习的核心组件与概念解析之神经网络基础】
大家好!今天咱们一头扎进深度学习的神秘领域,好好探索一下其最重要的基石 —— 神经网络。不管你是深度学习的新手小白,还是已经接触过一些基础概念,这篇文章都能助力你更透彻地理解神经网络的原理和运作机制。咱们从最基础的知识入手,一步步揭开神经网络的神秘面纱! 一、…...
Python中如何进行数据库连接?
在 Python 中进行数据库连接,不同的数据库需要使用不同的库。下面分别介绍几种常见数据库(SQLite、MySQL、PostgreSQL)的连接方法。 1. 连接 SQLite 数据库 SQLite 是一种轻量级的嵌入式数据库,Python 标准库中自带了sqlite3模块…...
解析 WebGPU 中 device.createBuffer 的参数意义
在 WebGPU 开发里,device.createBuffer 方法扮演着至关重要的角色,它用于创建一个 GPU 缓冲区对象,这个对象能够存储顶点数据、索引数据、统一数据等。下面我们就来详细剖析该方法各个参数的意义。 1. size:决定缓冲区容量 size …...
PLC的集成RAM,存储器卡,用户程序存储空间,数据存储容量分别指的什么,有什么关联?
1. 集成RAM 定义:集成RAM(随机存取存储器)是PLC内部的高速易失性存储器,用于临时存储运行时的数据(如输入/输出状态、中间变量、计数器/定时器的当前值等)。 特点: 易失性:断电后数…...
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接口的颜色并不是判断版本的可靠标准,但根据行业常见规范分析如下: USB接口颜色与版本对照表: 接口颜色常见版本内部触点数量传输速度黑色USB2.04触点480 Mbps (60 MB/s)白色USB2.0(多…...
2025百度快排技术分析:模拟点击与发包算法的背后原理
一晃做SEO已经15年了,2025年还有人问我如何做百度快速排名,我能给出的答案就是:做好内容的前提下,多刷刷吧!百度的SEO排名算法一直是众多SEO从业者研究的重点,模拟算法、点击算法和发包算法是百度快速排名的…...
idea 2019.3常用插件
idea 2019.3常用插件 文档 idea 2019.3常用插件idea 2023.3.7常用插件 idea 2019.3常用插件 插件名称插件版本说明1AceJump3.5.9AceJump允许您快速将插入符号导航到编辑器中可见的任何位置。只需按“ctrl;”,键入一个字符,然后在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 关键字输出: 3.3 nonlocal关键…...
WPF7-数据绑定基础
1. WPF数据绑定试验 1.1. 数据绑定的核心实现1.2. {Binding}语法1.3. 理解 DataContext 1. WPF数据绑定试验 以下是一个简单的 WPF 数据绑定示例,使用两个TextBox控件分别表示Name和Age来进行进行数据绑定试验。 数据模型类 创建一个 Person 类,包含…...
http 与 https 的区别?
HTTP(超文本传输协议)和 HTTPS(安全超文本传输协议)是互联网通信的基础协议。随着网络技术的发展和安全需求的提升,HTTPS变得越来越重要。本文将深入探讨HTTP与HTTPS之间的区别,包括其工作原理、安全性、性能、应用场景及未来发展等。 1. HTTP与HTTPS的基本概念 1.1 HT…...
大数据学习(49) - Flink按键分区状态(Keyed State)
&&大数据学习&& 🔥系列专栏: 👑哲学语录: 承认自己的无知,乃是开启智慧的大门 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一下博主哦ᾑ…...
IP 路由基础 | 路由条目生成 / 路由表内信息获取
注:本文为 “IP 路由” 相关文章合辑。 未整理去重。 IP 路由基础 秦同学学学已于 2022-04-09 18:44:20 修改 一. IP 路由产生背景 我们都知道 IP 地址可以标识网络中的一个节点,并且每个 IP 地址都有自己的网段,各个网段并不相同…...
COBOL语言的移动应用开发
COBOL语言的移动应用开发探讨 引言 在信息技术快速发展的今天,移动应用开发已成为各行各业不可或缺的一部分。许多企业和开发者纷纷转向使用新兴的编程语言和开发工具,以满足不断变化的用户需求。然而,作为一种历史悠久的编程语言ÿ…...
TCP协议(Transmission Control Protocol)
TCP协议,即传输控制协议,其最大的特征就是对传输的数据进行可靠、高效的控制,其段格式如下: 源端口和目的端口号表示数据从哪个进程来,到哪个进程去,四位报头长度表示的是TCP头部有多少个4字节,…...
C语言数组之二维数组
C语言 主要内容 数组 二维数组 数组 二维数组 定义 二维数组本质上是一个行列式的组合,也就是说二维数组由行和列两部分组成,属于多维数组。二维数组数据是通过行列进行解读。二维数组可被视为一个特殊的一维数组,相当于二维数组又是一…...
计算机专业知识【软件开发中的常用图表:E - R图、HIPO、DFD、N - S、PAD详解】
在软件开发过程中,有许多种图表工具被用于不同阶段的设计和分析,帮助开发者更清晰地理解系统结构、数据流程和算法逻辑。下面将详细介绍E - R图、HIPO图、DFD图、N - S图和PAD图,包括它们的样子和用途。 一、E - R图(实体 - 联系…...
多人协同开发 —— 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程序,那么使用fmt.Scan函数输入数据的时候就会报错,我们需要修改launch.json文件,将Go程序运行在shell终端上。 main.go package mainimport "fmt"func main() {var n intfmt.Scan(&n)v…...