JAVA AOP简单实践(基于SpringBoot)
天行健,君子以自强不息;地势坤,君子以厚德载物。
每个人都有惰性,但不断学习是好好生活的根本,共勉!
文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。
床前明月光,疑是地上霜。
举头望明月,低头思故乡。
——《静夜思》
文章目录
- JAVA AOP简单实践(基于SpringBoot)
- 1. 依赖引入
- 2. 完整依赖
- 3. 项目包结构
- 4. 项目启动类
- 5. 切面类
- 5.1 类创建
- 5.2 切点实现
- 5.3 前置通知
- 5.4 环绕通知
- 5.5 后置通知
- 5.6 返回通知
- 5.7 报错通知
- 5.8 完整切面类代码
- 6. 请求接口的实现
- 6.1 AopTestController.java
- 6.2 AopTest2Controller.java
- 6.3 AopTest3Controller.java
- 7. 测试接口
- 7.1 AopTestController.java的方法
- 7.2 AopTest2Controller.java的方法
- 7.3 AopTest3Controller.java的方法
- 8. 输出打印
- 8.1 test1输出结果
- 8.2 test2输出结果
- 8.3 test3输出结果
- 9. 总结
- 加分加分
- 1. 加分
- 2. 加分
- 3. 加分
- 4. 加分
- 4.1 加分1
- 4.2 加分2
- 4.3 加分3
- 4.4 加分4
关于aop的完整详细版可跳转到链接:Java AOP 介绍与实践
JAVA AOP简单实践(基于SpringBoot)
以下为AOP的简单实现
本项目demo以springboot框架实现
1. 依赖引入
引入aop的依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>2.7.18</version></dependency>
当然了,除了aop的依赖,本demo中还用到了其他依赖
2. 完整依赖
项目的所有依赖如下
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.hslb</groupId><artifactId>aop_demo</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.18</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>2.7.18</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.32</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.34</version></dependency></dependencies></project>
3. 项目包结构
该demo的包结构如下,可自行创建,主要为了测试aop匹配不同层级的包的情况
4. 项目启动类
AopApplication.java
package com.aop;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;/*** @ClassDescription: 项目启动类* 使用@EnableAspectJAutoProxy(proxyTargetClass = true)开启aop* @JdkVersion: 1.8* @Author: 李白* @Created: 2024/12/21 14:33*/
@EnableAspectJAutoProxy(proxyTargetClass = true)
@SpringBootApplication
public class AopApplication {public static void main(String[] args) {SpringApplication.run(AopApplication.class, args);}}
5. 切面类
以下切面类分多个部分进行拆分实现,最后有完整的切面类代码
5.1 类创建
创建切面类AopAspectJ.java
并在类上使用注解@Aspect标记该类为切面类,同时需要使用@Component注解将其标记为Bean
package com.aop.common;import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;/*** @ClassDescription: aop切面类* @JdkVersion: 1.8* @Author: 李白* @Created: 2024/12/21 14:35*/
@Aspect
@Component
public class AopAspectJ {}
5.2 切点实现
在AopAspectJ.java类中定义一个切点方法
方法修饰符为public
返回值为void
方法名自定义
在方法上使用@Pointcut注解将其标记为切点方法
同时在注解中将匹配条件填入,以此来进行拦截满足条件的方法
/*** 定义切入点方法,方法名自定义,无参数,无内容,定义的方法名后续注解需要使用,以此方法切入*/
// @Pointcut(value = "execution(* com.aop..*(..))")
// @Pointcut(value = "execution(* com.aop..*.*(..))")
// @Pointcut(value = "execution(* com.aop.controller.*.*(..))")@Pointcut(value = "execution(* com.aop.*.*.*(..))")public void pointcut(){}
5.3 前置通知
在AopAspectJ.java类中定义前置通知,进行方法执行前的逻辑实现
/*** 定义前置通知@Beafore*/@Before(value = "pointcut()")public void before(){System.out.println("前置通知@Before------------------>");}
5.4 环绕通知
在AopAspectJ.java类中定义环绕通知,进行方法执行前、中、后的逻辑实现
/*** 定义环绕置通知@Around* @param proceedingJoinPoint 连接点* @throws Throwable 抛错*/@Around(value = "pointcut()")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {//前置逻辑System.out.println("环绕通知@Around 执行前------------------>");//执行被通知的方法proceedingJoinPoint.proceed();//后置逻辑System.out.println("环绕通知@Around 执行后------------------>");}
5.5 后置通知
在AopAspectJ.java类中定义后置通知,进行方法执行后的逻辑实现
/*** 定义后置通知@After*/@After(value = "pointcut()")public void after(){System.out.println("后置通知@After------------------>");}
5.6 返回通知
在AopAspectJ.java类中定义返回通知,进行方法执行后并成功返回后的逻辑实现
/*** 定义返回通知@AfterReturning* @param joinPoint 连接点* @param result 返回结果* @return 返回*/@AfterReturning(value = "pointcut()", returning = "result")public JSONObject afterReturning(JoinPoint joinPoint, JSONObject result){System.out.println("返回通知@AfterReturning------------------>");return null;}
5.7 报错通知
在AopAspectJ.java类中定义报错通知,进行方法执行失败后的逻辑实现
/*** 定义报错通知@AfterThrowing*/@AfterThrowing(value = "pointcut()")public void afterThrowing(){System.out.println("报错通知@AfterThrowing------------------>");}
5.8 完整切面类代码
以下为切面类的完整代码实现
AopAspectJ.java
package com.aop.common;import com.alibaba.fastjson.JSONObject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;/*** @ClassDescription: aop切面类* @JdkVersion: 1.8* @Author: 李白* @Created: 2024/12/21 14:35*/
@Aspect
@Component
public class AopAspectJ {/*** 定义切入点方法,方法名自定义,无参数,无内容,定义的方法名后续注解需要使用,以此方法切入*/
// @Pointcut(value = "execution(* com.aop..*(..))")
// @Pointcut(value = "execution(* com.aop..*.*(..))")
// @Pointcut(value = "execution(* com.aop.controller.*.*(..))")@Pointcut(value = "execution(* com.aop.*.*.*(..))")public void pointcut(){}/*** 定义前置通知@Beafore*/@Before(value = "pointcut()")public void before(){System.out.println("前置通知@Before------------------>");}/*** 定义环绕置通知@Around* @param proceedingJoinPoint 连接点* @throws Throwable 抛错*/@Around(value = "pointcut()")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {//前置逻辑System.out.println("环绕通知@Around 执行前------------------>");//执行被通知的方法proceedingJoinPoint.proceed();//后置逻辑System.out.println("环绕通知@Around 执行后------------------>");}/*** 定义后置通知@After*/@After(value = "pointcut()")public void after(){System.out.println("后置通知@After------------------>");}/*** 定义返回通知@AfterReturning* @param joinPoint 连接点* @param result 返回结果* @return 返回*/@AfterReturning(value = "pointcut()", returning = "result")public JSONObject afterReturning(JoinPoint joinPoint, JSONObject result){System.out.println("返回通知@AfterReturning------------------>");return null;}/*** 定义报错通知@AfterThrowing*/@AfterThrowing(value = "pointcut()")public void afterThrowing(){System.out.println("报错通知@AfterThrowing------------------>");}}
6. 请求接口的实现
在不同的包中创建请求接口,接口类中的请求路径不同且输出也不同,然后通过表达式不同的拦截条件进行测试不同的接口
查看输出内容即可验证
6.1 AopTestController.java
com.aop.controller.AopTestController.java类
package com.aop.controller;import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.*;/*** @ClassDescription: 请求测试类* @JdkVersion: 1.8* @Author: 李白* @Created: 2024/12/21 14:34*/
@RestController
@RequestMapping(value = "/aop")
public class AopTestController {@GetMapping(value = "test1")public JSONObject test1(@RequestHeader("token")String token,@RequestParam("username")String username){JSONObject jsonObject = new JSONObject();jsonObject.put("token", token);jsonObject.put("username", username);System.out.println("aop test1 token: "+token+" username: "+username);return jsonObject;}}
6.2 AopTest2Controller.java
com.aop.common.AopTest2Controller.java类
package com.aop.common;import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.*;/*** @ClassDescription: 请求测试类* @JdkVersion: 1.8* @Author: 李白* @Created: 2024/12/21 14:34*/
@RestController
@RequestMapping(value = "/aop2")
public class AopTest2Controller {@GetMapping(value = "test2")public JSONObject test1(@RequestHeader("token")String token,@RequestParam("username")String username){JSONObject jsonObject = new JSONObject();jsonObject.put("token", token);jsonObject.put("username", username);System.out.println("aop test2 token: "+token+" username: "+username);return jsonObject;}}
6.3 AopTest3Controller.java
com.aop.common.test.AopTest3Controller.java类
package com.aop.common.test;import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.*;/*** @ClassDescription: 请求测试类* @JdkVersion: 1.8* @Author: 李白* @Created: 2024/12/21 14:34*/
@RestController
@RequestMapping(value = "/aop3")
public class AopTest3Controller {@GetMapping(value = "test3")public JSONObject test1(@RequestHeader("token")String token,@RequestParam("username")String username){JSONObject jsonObject = new JSONObject();jsonObject.put("token", token);jsonObject.put("username", username);System.out.println("aop test3 token: "+token+" username: "+username);return jsonObject;}}
7. 测试接口
启动项目
使用postman进行请求接口测试
依次调用三个接口
7.1 AopTestController.java的方法
请求方式
Get
请求地址
127.0.0.1:8080/aop/test1
请求头参数
请求参数
7.2 AopTest2Controller.java的方法
请求方式
Get
请求地址
127.0.0.1:8080/aop2/test2
请求参数和值都与上一个接口一样
7.3 AopTest3Controller.java的方法
请求方式
Get
请求地址
127.0.0.1:8080/aop3/test3
请求参数和值都与上一个接口一样
8. 输出打印
在postman中分别调用三个接口
控制台输出内容依次如下
8.1 test1输出结果
AopTestController.java中test1的输出结果如下
环绕通知@Around 执行前------------------>
前置通知@Before------------------>
aop test1 token: 13579 username: libai
返回通知@AfterReturning------------------>
后置通知@After------------------>
环绕通知@Around 执行后------------------>
8.2 test2输出结果
AopTest2Controller.java中test1的输出结果如下
环绕通知@Around 执行前------------------>
前置通知@Before------------------>
aop test2 token: 13579 username: libai
返回通知@AfterReturning------------------>
后置通知@After------------------>
环绕通知@Around 执行后------------------>
8.3 test3输出结果
AopTest3Controller.java中test1的输出结果如下
aop test3 token: 13579 username: libai
9. 总结
因为我们的表达式是execution(* com.aop.*.*.*(..))
该表达式拦截的是com.aop包下一级包中的所有类的所有方法,不包含下一级包的子包
test1和test2都是aop下一级包的类中的方法
test1是aop.controller包下的类的方法
test2是aop.common包下的类的方法
而test3是aop.common.test包下类的方法,已经是aop包下一级包common包的子包test包下的方法,多了一级,因此拦截不到
感谢阅读,祝君暴富!
版权声明:
- 作者:寒山李白
- 博客地址:https://hanshan.blog.csdn.net/
- 版权:本作品采用《创作共享许可证》进行许可,根据该许可授权的内容可在符合本许可证条款的前提下自由使用、、修改和创作衍生作品。
版权许可介绍:
本文采用CC BY-NC-SA许可证
此许可允许在使用者仅出于非商业目的以任何媒体或格式分发、重新混合、改编和构建材料,并且前提是注明创作者。如果您重新混合、改编或基于该材料进行构建,则必须按照相同的条款对修改后的材料进行许可。
更多信息请访问以下网址查看:
版权官网 https://creativecommons.org/licenses/by-nc-sa/4.0/
中文翻译 https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh-hans
文章结束
--------------------------------------------------------------------------------------------------------------------------------------
以下内容增加文章评分用,可忽略
加分加分
黄河之水天上来,奔流到海不复回
高堂明镜悲白发,朝如青丝暮成雪
1. 加分
黄河之水天上来,奔流到海不复回
高堂明镜悲白发,朝如青丝暮成雪
2. 加分
黄河之水天上来,奔流到海不复回
高堂明镜悲白发,朝如青丝暮成雪
3. 加分
寒山李白
寒山李白
4. 加分
账号密码
名称 | 密码 |
---|---|
李白 | 123 |
4.1 加分1
账号密码
名称 | 密码 |
---|---|
李白 | 123 |
4.2 加分2
账号密码
名称 | 密码 |
---|---|
李白 | 123 |
4.3 加分3
账号密码
名称 | 密码 |
---|---|
李白 | 123 |
4.4 加分4
账号密码
名称 | 密码 |
---|---|
李白 | 123 |
相关文章:

JAVA AOP简单实践(基于SpringBoot)
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...

java agent的使用【通俗易懂版】
一、静态代理Agent 1.生成Agent的jar包 (1)创建Agent项目,引入javassist.jar包 (2)编写premain方法 import java.lang.instrument.Instrumentation;public class Agent1 {public static void premain(Stri…...

大模型学习指南
随着人工智能的迅猛发展,大模型成为了技术前沿的璀璨明星。踏入大模型学习领域,需要在多个关键方面下功夫。 扎实的数学功底是基石。线性代数为理解多维数据、矩阵运算提供支撑,像大模型中权重矩阵的处理就离不开它;概率论与数理…...

单片机:实现定时器中断(数码管读秒+LED闪烁)(附带源码)
单片机实现定时器中断:数码管读秒与LED闪烁 在单片机项目中,定时器中断是一个常见的应用,用于实现定时任务,例如定时更新显示或控制周期性事件。本文将介绍如何使用定时器中断实现数码管读秒和LED闪烁功能。通过使用定时器中断&a…...

STM32单片机芯片与内部33 ADC 单通道连续DMA
目录 一、ADC DMA配置——标准库 1、ADC配置 2、DMA配置 二、ADC DMA配置——HAL库 1、ADC配置 2、DMA配置 三、用户侧 1、DMA开关 (1)、标准库 (2)、HAL库 2、DMA乒乓 (1)、标准库 ÿ…...

【0376】Postgres内核 分配 last safe MultiXactId
上一篇: 【0375】Postgres内核 XLOG 之 设置下一个待分配 MultiXactId 和 offset 文章目录 1. 最后一个安全的 MultiXactId1.1 计算 multi wrap limit1.2 计算 multi stop limit1.3 计算 multi warn limit1.4 计算 multi vacuum limit2. 初始化 MultiXactState 成员3. 完成 mu…...

php时间strtotime函数引发的问题 时间判断出错
在 PHP 中,strtotime 函数能处理的最大时间范围取决于您的系统和 PHP 版本。 一般来说,它可以处理的时间范围从 1901 年 12 月 13 日到 2038 年 1 月 19 日。超过这个范围可能会导致不可预测的结果或错误。 如果您需要处理更大范围的时间,可能…...

Kibana:LINUX_X86_64 和 DEB_X86_64两种可选下载方式的区别
最近需要在vm(操作系统是 Ubuntu 22.04.4 LTS,代号 Jammy。这是一个基于 x86_64 架构的 Linux 发行版)上安装一个7.17.8版本的Kibana,并且不采用docker方式。 在下载的时候发现有以下两个选项,分别是 LINUX_X86_64 和 …...

【LeetCode每日一题】 LeetCode 151.反转字符串中的单词
LeetCode 151.反转字符串中的单词 题目描述 给你一个字符串 s ,请你反转字符串中单词的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。 注意:…...

gitlab克隆仓库报错fatal: unable to access ‘仓库地址xxxxxxxx‘
首次克隆仓库,失效了,上网查方法,都说是网络代理的问题,各种清理网络代理后都无效,去问同事: 先前都是直接复制的网页url当做远端url,或者点击按钮‘使用http克隆’ 这次对于我来说有效的远端u…...

在已有vue cli项目中添加单元测试配置
使用的是vue cli ^4.0.0的脚手架,项目采用的vue2进行编写,项目本身是没有使用单元测试的。应该挺多项目还是使用的vue2的项目进行开发的,自己在开发中过程中,还是发生了挺多需要记录原来功能的情况,这个时候去翻文档明…...

企业级NoSql数据库REDIS集群
1.1数据库主要分为两大类:关系型数据库与 NoSQL数据库 关系型数据库,是建立在关系模型基础上的数把库,其借助于集合代数等数学概念和方法来处理数据库中的数掘主流的 MySQLOracle、Ms sOLSerer和 DB2 都属于这类传统数据库 NoSQL数据库,全称…...

HTML与数据抓取:GET与POST方法详解
讲GET和POST就不能只讲GET和POST 你要讲HTTP请求的基本概念: HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上应用最为广泛的一种网络协议,主要用于Web浏览器与Web服务器之间的数据通信。HTTP是一个基于…...

【es6复习笔记】模板字符串(3)
介绍 模板字符串是 ES6 引入的一种新的字符串声明方式,它使用反引号()来定义字符串,而不是单引号()或双引号(")。模板字符串可以包含变量、表达式和换行符,这使得它…...

cursor保存更改操作技巧
1. 当我们在agent模式时,要求cursor更改代码时,cursor回答后,就已经更改了代码了,这时候就可以对程序进行编译和测试, 不一定先要点” accept“, 先测试如果没有问题再点“accept”,这样composer就会多一条…...

ASP.NET |日常开发中定时任务详解
ASP.NET |日常开发中定时任务详解 前言一、定时任务的概念与用途1.1 定义1.2 应用场景 二、在ASP.NET中实现定时任务的方式2.1 使用System.Timers.Timer2.2 使用Quartz.NET 三、定时任务的部署与管理3.1 部署考虑因素3.2 管理与监控 结束语优质源码分享 ASP.NET &am…...

【零基础保姆级教程】制作自己的数据集(二)——Labelme的安装与使用及常见的报错解决方法
前段时间安装了Labelimg,网上有些博客写着Labelme能进行语义分割的标注,但UI窗口就那么大找不着选项,只能打矩形框,为了能够标注自己的分割数据集,遂写下该教程以供参考。 采用Labelimg进行目标检测标注的教程如下。 …...

Move AI技术浅析(二):输入与预处理
一、视频输入模块 1.1 视频输入步骤详解 视频输入模块的主要任务是接收视频数据,并将其转换为后续处理所需的格式。具体步骤: 1.1.1 视频读取 步骤:从文件系统、网络流或摄像头读取视频数据。技术:使用 OpenCV 的 cv2.VideoCa…...

实践KDTS-WEB从mysql迁移到kingbasev9
数据库国产化替代数据迁移是一个复杂且关键的过程。这涉及到将原有数据库中的数据准确、完整地迁移到新的国产数据库中,同时确保数据的完整性和一致性。人大金仓提供了强大的数据库迁移工具(KDTS)对同构、异构数据库数据迁移; 数…...

WebGIS实战开源项目:智慧机场三维可视化(学习笔记)
From:新中地 1.简介 智慧机场解决方案,基于数字化大平台,融合AI、大数据、IoT、视频云、云计算等技术,围绕机场“运控、安防、服务”三大业务领域,构建“出行一张脸”及“运行一张图”两大场景化解决方案。 https://…...

2025年PMP项目管理考试时间一览表
PMP认证是全球项目管理领域公认的权威认证,它不仅能证明你在项目管理方面的专业水平,还能大大提升你的职场竞争力! 随着企业对项目管理人才的需求不断增长,获得PMP认证将为你带来更多的职业机会和高薪职位。 为了帮助大家合理安排…...

20241224在ubuntu20.04.6下的终端分屏软件terminator的安装以及使用
20241224在ubuntu20.04.6下的终端分屏软件terminator的安装以及使用 2024/12/24 18:35 百度:终端分屏软件 https://blog.csdn.net/weixin_49693003/article/details/143683326 可以实现终端分屏的工具:terminator 安装: sudo apt-get insta…...

打造高效租赁小程序让交易更便捷
内容概要 在如今节奏飞快的商业世界里,租赁小程序如同一只聪明的小狐狸,迅速突围而出,成为商家与消费者之间的桥梁。它不仅简化了交易流程,还在某种程度上将传统租赁模式带入了互联网时代。越来越多的企业意识到,这种…...

光谱相机在农业中的具体应用案例
作物生长监测与产量预测 美国爱荷华州玉米种植园:农场主使用无人机搭载高光谱相机,定期对玉米田进行拍摄。通过分析光谱数据,获取玉米的叶面积指数、叶绿素含量等生长参数。在玉米生长关键期,依据这些参数及时调整施肥和灌溉方案…...

Linux RTC 驱动框架
目录 一、实时时钟(RTC)介绍1.1 概述1.2 功能1.3 应用场景1.4 工作原理1.5 对外接口1.6 常见 RTC 芯片1.7 在 Linux 系统中的应用1.8 注意事项 二、Linux 内核 RTC 驱动框架2.1 相关源码文件介绍2.2 核心数据结构2.2.1 struct rtc_device2.2.2 rtc_class…...

msyql数据库读写分离搭建
一.mysql读写分离:缓解主服务器的压力1.概念:主服务器写数据,从服务器读数据2.实现方法:客户端分离: 开发手动分离地址服务端分离: 数据库与应用之间加一个中间件,分离读写请求mysql-proxy,mysql-route,maxscaleamoeba,cobar,mycat2atlas,kingshard,vitees3.mycat配置方法:冷配…...

WWW23-多行为级联|级联图卷积网络的多行为推荐
论文:https://arxiv.org/abs/2303.15720 代码:https://github.com/SS-00-SS/MBCGCN 这篇论文MB-CGCN和上一篇CRGCN是同一个团队的,都是级联的方式。一个用了残差,一个用了特征转换,文章最后有discussion讨论了两者的不…...

【EthIf-14】EthIfGeneral容器配置-02
1.实际EthIfGeneral的配置实例 关闭DET接口开启发送确认中断开启接收中断主周期接收timeout主周期 2. 代码实例参考 阅读此部分代码,搞清楚代码分为几个section,大概瞄一眼就好,不用深究其含义,只需有一个宏观的层次结构的映像即可。 //Appl/GenData/EthIf_Cfg.h #...

近实时”(NRT)搜索、倒排索引
近实时(Near Real-Time, NRT)搜索 近实时(NRT)搜索是 Elasticsearch 的核心特性之一,指的是数据在被写入到系统后,可以几乎立即被搜索和查询到。虽然它不像传统数据库那样完全实时,但它的延迟通…...

Ubuntu20.04安装openMVS<成功>.colmap<成功>和openMVG<失败(已成功)>
一、安装openMVS 参考官方文档 sudo apt-get -y install git mercurial cmake libpng-dev libjpeg-dev libtiff-dev libglu1-mesa-dev eigen git clone https://gitlab.com/libeigen/eigen --branch 3.4 mkdir eigen_build cd eigen_build &&\cmake . ../eigen -…...