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

Java动态代理模式深度解析

1. 动态代理基础

1.1 核心组件

  • Proxy 类:动态生成代理对象的工厂类,核心方法为 newProxyInstance()

  • InvocationHandler 接口:代理逻辑的处理器,所有方法调用会转发到其 invoke() 方法。

1.2 实现步骤

  1. 定义接口:代理基于接口实现。

    public interface UserService {void addUser(String username);
    }
  2. 实现类(真实对象)

    public class UserServiceImpl implements UserService {public void addUser(String username) {System.out.println("添加用户: " + username);}
    }
  3. 实现 InvocationHandler

    public class LoggingHandler implements InvocationHandler {private final Object target;public LoggingHandler(Object target) { this.target = target; }@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("方法调用前: " + method.getName());Object result = method.invoke(target, args);System.out.println("方法调用后");return result;}
    }
  4. 创建代理对象

    UserService realService = new UserServiceImpl();
    UserService proxy = (UserService) Proxy.newProxyInstance(realService.getClass().getClassLoader(),new Class[]{UserService.class},new LoggingHandler(realService)
    );
    proxy.addUser("Alice");

1.3 底层原理

  • 动态生成代理类:运行时生成 $ProxyN 类字节码。

  • 方法调用流程:代理类方法调用委托给 InvocationHandler

1.4 应用场景

  • 日志记录、性能监控、事务管理、权限控制等横切关注点。

  • RPC 框架中的远程调用封装。

1.5 优缺点

优点缺点
业务逻辑与切面逻辑解耦仅支持接口代理
无需为每个类编写静态代理反射调用存在性能开销

1.6 高级话题

  • CGLIB 代理:通过继承实现类代理(需引入 cglib 依赖)。

  • Lambda 简化:Java 8+ 使用 Lambda 表达式定义 InvocationHandler

    UserService proxy = (UserService) Proxy.newProxyInstance(loader,new Class[]{UserService.class},(p, method, args) -> {System.out.println("Lambda 代理逻辑");return method.invoke(target, args);}
    );

2. 动态代理在 Spring Boot 中的应用

2.1 核心应用场景

场景实现方式示例
事务管理@Transactional + TransactionInterceptor方法执行前后管理事务
AOP 切面逻辑@Aspect + Advisor日志、权限校验、性能监控
Spring Data JPA动态生成 Repository 实现类findByUsername 自动实现
全局异常处理@ControllerAdvice统一处理 Controller 层异常

2.2 实现机制

  • 代理方式选择

    • JDK 动态代理:默认代理接口(需实现接口)。

    • CGLIB 代理:代理类(无接口时使用),Spring Boot 2.x+ 默认启用。

  • 代理生成流程

    1. Bean 初始化时检测是否需要代理。

    2. 匹配切面规则(通过 Pointcut)。

    3. 生成代理对象并织入逻辑。

2.3 调试与优化

  • 查看代理类

    # JDK 代理
    -Djdk.proxy.ProxyGenerator.saveGeneratedFiles=true
    # CGLIB 代理
    -Dcglib.debugLocation=/tmp/cglib
  • 验证代理类型

    boolean isJdkProxy = Proxy.isProxyClass(bean.getClass());
    boolean isCglibProxy = bean.getClass().getName().contains("$$EnhancerBySpringCGLIB$$");

2.4 典型问题与解决方案

  • 自调用失效问题

    // 错误:同类方法直接调用,事务失效
    public void outerMethod() {innerMethod(); // 未通过代理调用
    }// 正确:通过代理对象调用
    @Autowired
    private UserService self; // 注入代理后的 Bean
    public void outerMethod() {self.innerMethod();
    }

3. 多 Service 动态代理实现方案

3.1 通用代理实现

  • 支持多个 Service 的 InvocationHandler

    public class LoggingHandler implements InvocationHandler {private final Object target;public LoggingHandler(Object target) { this.target = target; }@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("[Log] 调用方法: " + method.getName());return method.invoke(target, args);}
    }
  • 代理工厂类

    public class ProxyFactory {public static <T> T createProxy(T target, Class<T> interfaceType) {return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),new Class<?>[]{interfaceType},new LoggingHandler(target));}
    }

3.2 结合 Spring 容器

  • 配置类定义代理 Bean

    @Configuration
    public class ProxyConfig {@Beanpublic UserService userService() {return ProxyFactory.createProxy(new UserServiceImpl(), UserService.class);}@Beanpublic OrderService orderService() {return ProxyFactory.createProxy(new OrderServiceImpl(), OrderService.class);}
    }
  • 使用代理对象

    @Service
    public class AppService {@Autowiredprivate UserService userService;@Autowiredprivate OrderService orderService;public void execute() {userService.addUser("Alice");orderService.createOrder("ORDER_001");}
    }

3.3 完整代码示例

  • 接口定义

    public interface OrderService {void createOrder(String orderId);
    }
  • 实现类

    public class OrderServiceImpl implements OrderService {@Overridepublic void createOrder(String orderId) {System.out.println("创建订单: " + orderId);}
    }
  • 运行示例

    public class Main {public static void main(String[] args) {UserService userProxy = ProxyFactory.createProxy(new UserServiceImpl(), UserService.class);OrderService orderProxy = ProxyFactory.createProxy(new OrderServiceImpl(), OrderService.class);userProxy.addUser("Bob");orderProxy.createOrder("ORDER_002");}
    }

4. 总结

  • 动态代理的价值:通过解耦核心逻辑与横切关注点,提升代码复用性和可维护性。

  • 在 Spring Boot 中的实践

    • 默认使用 CGLIB 代理,支持类代理。

    • 广泛应用于事务、AOP、数据访问等场景。

  • 多 Service 代理方案:通过工厂模式和 Spring 容器管理,实现统一代理逻辑。

JDK 动态代理和CGLIB 代理的区别

一、CGLIB 代理示例

1. 添加依赖

CGLIB 需要额外引入依赖(Spring Boot 默认已包含):

<!-- Maven 依赖 -->
<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version>
</dependency>
2. 定义目标类(无需接口)
public class UserService {public void addUser(String username) {System.out.println("添加用户: " + username);}
}
3. 实现方法拦截器 MethodInterceptor
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;public class LoggingInterceptor implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("方法调用前: " + method.getName());Object result = proxy.invokeSuper(obj, args); // 调用父类(原始类)方法System.out.println("方法调用后");return result;}
}
4. 生成 CGLIB 代理对象
import net.sf.cglib.proxy.Enhancer;public class CglibProxyDemo {public static void main(String[] args) {// 创建增强器Enhancer enhancer = new Enhancer();enhancer.setSuperclass(UserService.class);          // 设置父类(目标类)enhancer.setCallback(new LoggingInterceptor());    // 设置回调(拦截器)// 创建代理对象UserService proxy = (UserService) enhancer.create();// 调用方法proxy.addUser("Alice");}
}
5. 输出结果
方法调用前: addUser
添加用户: Alice
方法调用后

二、JDK 动态代理 vs CGLIB 代理对比

对比维度JDK 动态代理CGLIB 代理
实现机制基于接口,通过 Proxy 类生成代理对象基于继承,通过修改字节码生成目标类的子类作为代理
目标类要求必须实现至少一个接口可以代理无接口的类(通过继承)
性能生成代理对象较快,但反射调用方法较慢生成代理对象较慢(需操作字节码),但方法调用较快
方法覆盖只能代理接口中的方法可以代理目标类中所有非 final 方法
依赖关系无需额外依赖(JDK 内置)需要引入 cglib 库
应用场景Spring 中代理接口实现类(如 @RepositorySpring 中代理无接口的类(如 @Service@Controller
局限性无法代理未实现接口的类无法代理 final 类或 final 方法

三、关键区别详解

1. 实现原理
  • JDK 动态代理

    • 基于 Java 反射机制,运行时动态生成实现指定接口的代理类。

    • 代理类名格式:$ProxyN(如 $Proxy0)。

    // 生成的代理类伪代码
    public final class $Proxy0 extends Proxy implements UserService {public final void addUser(String username) {super.h.invoke(this, m3, new Object[]{username});}
    }
  • CGLIB 代理

    • 通过 ASM 字节码操作框架,生成目标类的子类作为代理。

    • 代理类名格式:TargetClass$$EnhancerByCGLIB$$...

    // 生成的代理类伪代码
    public class UserService$$EnhancerByCGLIB$$12345 extends UserService {private MethodInterceptor interceptor;public void addUser(String username) {interceptor.intercept(this, method, args, methodProxy);}
    }
2. 性能对比
操作JDK 动态代理CGLIB 代理
代理对象生成速度慢(需操作字节码)
方法调用速度较慢(反射调用)快(直接调用父类方法)
3. Spring 中的选择策略
  • Spring Boot 2.x+:默认使用 CGLIB 代理(通过 @EnableAspectJAutoProxy(proxyTargetClass = true))。

  • 强制使用 JDK 代理:若目标类实现了接口,可通过配置 proxyTargetClass = false 切换。

4. 代码示例对比
场景JDK 动态代理CGLIB 代理
目标类定义必须实现接口可以是普通类
代理对象创建Proxy.newProxyInstance()Enhancer.create()
方法调用入口InvocationHandler.invoke()MethodInterceptor.intercept()

四、如何选择代理方式?

  1. 有接口且需轻量级代理 → JDK 动态代理。

  2. 无接口或需代理类方法 → CGLIB 代理。

  3. 目标类有 final 修饰 → 无法使用 CGLIB,需改用 JDK 动态代理或重构代码。


五、总结

  • JDK 动态代理:轻量级接口代理方案,适合简单场景。

  • CGLIB 代理:功能更强大的类代理方案,适合复杂场景(无接口或需高性能调用)。

  • Spring 最佳实践:优先使用 CGLIB 代理,避免接口依赖问题(如 Spring Data JPA 的 Repository 实现)。

相关文章:

Java动态代理模式深度解析

1. 动态代理基础 1.1 核心组件 Proxy 类&#xff1a;动态生成代理对象的工厂类&#xff0c;核心方法为 newProxyInstance()。 InvocationHandler 接口&#xff1a;代理逻辑的处理器&#xff0c;所有方法调用会转发到其 invoke() 方法。 1.2 实现步骤 定义接口&#xff1a;代…...

【WRF模拟】垂直层设置/与观测数据对比

【WRF模拟】垂直层设置/与观测数据对比 WRF 中 有关垂直层的namelist变量1. 主要垂直层设置参数2. 详细解释3. 典型设置示例WRF 输出的垂直剖面数据与观测数据进行比较WRF 采用 地形跟随坐标(terrain-following coordinate)WRF 输出的垂直剖面数据与观测数据进行比较参考WRF …...

植物知识分享论坛毕设

1.这四个文件直接是什么关系&#xff1f;各自都是什么作用&#xff1f;他们之间是如何联系的&#xff1f; 关系与联系 UserController.java 负责接收外部请求&#xff0c;调用 UserService.java 里的方法来处理业务&#xff0c; 而 UserService.java 又会调用 UserMapper.jav…...

可视化图解算法:链表中倒数(最后)k个结点

1. 题目 描述 输入一个长度为 n 的链表&#xff0c;设链表中的元素的值为ai &#xff0c;返回该链表中倒数第k个节点。 如果该链表长度小于k&#xff0c;请返回一个长度为 0 的链表。 数据范围&#xff1a;0≤n≤105&#xff0c;0 ≤ai≤109&#xff0c;0 ≤k≤109 要求&am…...

qt下载和安装教程国内源下载地址

qt不断在更新中&#xff0c;目前qt6日渐成熟&#xff0c;先前我们到官方下载或者国内镜像直接可以下载到exe文件安装&#xff0c;但是最近几年qt官方似乎在逐渐关闭旧版本下载通道&#xff0c;列为不推荐下载。但是qt5以其广泛使用和稳定性&#xff0c;以及积累大量代码使得qt5…...

html5表格实战-跨行跨列

效果如图 代码如图...

使用OBS进行webRTC推流参考

参考腾讯云官方文档&#xff1a; 云直播 OBS WebRTC 推流_腾讯云 说明非常详细&#xff0c;分为通过WHIP和OBS插件的形式进行推流。 注意&#xff1a;通过OBS插件的形式进行推流需要使用较低的版本&#xff0c;文档里有说明&#xff0c;需要仔细阅读。...

Rockchip --- 图像时延优化

通过配置wait-line&#xff0c;即图像采集多少行后提前输出buffer给ISP&#xff0c;而无需等待图像全部采集完毕。一般设置为图像采集一半后提前输出buffer给ISP &#xff08;一&#xff09;VICAP提前输出 Video Input CAPture是用于图像采集和处理的子系统 1. 通过dts配置 …...

微软 LIDA 库:基于大模型的自动化数据分析与可视化

微软 LIDA 库&#xff1a;基于大模型的自动化数据分析与可视化 一、核心架构与 LLM 交互流程 #mermaid-svg-UzSwZNKPlgrJUpej {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-UzSwZNKPlgrJUpej .error-icon{fill:#5…...

java-正则表达式-集合-泛型

正则表达式 正则表达式到底是什么东西&#xff1f; 在编写处理字符串的程序或网页时&#xff0c;经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说&#xff0c;正则表达式就是记录文本规则的代码。 http://tool.oschina.net/r…...

力扣刷题994. 腐烂的橘子

994. 腐烂的橘子 - 力扣&#xff08;LeetCode&#xff09; 使用bfs&#xff0c;先遍历所有的橘子&#xff0c;统计所有的橘子数量&#xff0c;然后把腐烂的橘子放入队列当中&#xff0c;然后进行bfs遍历&#xff0c;套用bfs的模版&#xff0c;但是每一次出队的橘子&#xff08…...

Kubernetes的Service详解

一、Service介绍 在 kubernetes 中&#xff0c; pod 是应用程序的载体&#xff0c;我们可以通过 pod 的 ip 来访问应用程序&#xff0c;但是 pod 的 ip 地址不是固定的&#xff0c;这也就意味着不方便直接采用pod 的 ip 对服务进行访问。 为了解决这个问题&#xff0c;kuberne…...

Linux目录理解

前言 最近在复习linux&#xff0c;发现有些目录总是忘记内容&#xff0c;发现有些还是得从原义和实际例子去理解会记忆深刻些。以下是个人的一些理解 Linux目录 常见的Linux下的目录如下&#xff1a; 1. 根目录 / (Root Directory) 英文含义&#xff1a;/ 是文件系统的根…...

vue中js简单创建一个事件中心/中间件/eventBus

vue中js简单创建一个事件中心/中间件/eventBus 目录结构如下&#xff1a; eventBus.js class eventBus {constructor() {this.events {};}// 监听事件on(event, callback) {if (!this.events[event]) {this.events[event] [];}this.events[event].push(callback);}// 发射…...

1~2 课程简介+ESP32-IDF环境搭建(虚拟机Linux环境下)

哔站“宸芯IOT”视频链接 一、课程内容介绍 1.什么是ESP32 ESP32是集成2.4GHz Wi-Fi和蓝牙双模的单芯片方案&#xff0c;具有超高的射频性能、稳定性、通用性和可靠性&#xff0c;以及超低的功耗&#xff0c;满足不同的功耗需求&#xff0c;适用于各种应用场景。ESP32是ESP8…...

Linux系统移植篇(十一)Linux 内核启动流程

要分析 Linux 启动流程&#xff0c;同样需要先编译一下 Linux 源码&#xff0c;因为有很多文件是需要编译才 会生成的。首先分析 Linux 内核的连接脚本文件 arch/arm/kernel/vmlinux.lds&#xff0c;通过链接脚本可以 找到 Linux 内核的第一行程序是从哪里执行的。vmlinux.lds …...

React19源码系列之Hooks(useId)

useId的介绍 https://zh-hans.react.dev/reference/react/useId useId 是 React 18 引入的一个新 Hook&#xff0c;主要用于生成全局唯一的 ID。在开发中&#xff0c;我们经常需要为元素&#xff08;如表单元素、模态框等&#xff09;生成唯一 ID&#xff0c;以便在 JavaScri…...

深度学习-149-langchain之如何不使用with_structured_output()从模型中返回结构化数据

文章目录 1 不使用with_structured_output()方法1.1 问题背景1.2 输出解析器1.3 远程deepseek大模型API2 基于提示词2.1 直接使用提示词2.2 少样本提示词3 直接提示和解析模型输出3.1 使用PydanticOutputParser3.1.1 构建解析器3.1.2 构建提示模板3.1.3 调用大模型3.1.4 调用链…...

SAP DOI EXCEL应用

【应用场景】采用DOI方式打开填充EXCEL数据 *&---------------------------------------------------------------------* *& 包含 ZFI1009R_TOP *&---------------------------------------------------------------------* TABLES:bkpf,bseg. D…...

RS485电路设计注意事项

&#xff08;一&#xff09;RS485的电平标准&#xff1a; RS485用缆线两端的电压差值来表示传递信号&#xff0c;逻辑“1”以两线间的电压差为2V~6V标识&#xff0c;逻辑“0”以两线间的电压差为-2V~-6V标识。由此可见&#xff0c;接口信号电平较低&#xff0c;不易损坏接口电路…...

Git 回退操作详解:带示例的“小白”指南

前言 在日常开发中&#xff0c;我们难免会遇到&#xff1a; 改错代码&#xff1a;推送之前才发现某些行根本就不该动提交错误&#xff1a;commit 信息打错、提交到错误分支想回到之前版本&#xff1a;测试时发现之前版本是好的&#xff0c;需要回去查看 这就需要用到 Git 的…...

PyQt5库 各种导入项的作用

from PyQt5.QtCore import QIODevice, QSharedMemory, pyqtSignal 这行代码是从 PyQt5 库中导入了几个类和信号&#xff0c;用于开发桌面应用程序。下面是每个导入项的详细解释&#xff1a; QIODevice: QIODevice 是 PyQt5 中的一个类&#xff0c;提供了对输入输出设备的抽象…...

Git下载安装(保姆教程)

目录 1、Git下载 2、Git安装&#xff08;windows版&#xff09; &#xff08;1&#xff09;启动安装程序 &#xff08;2&#xff09;阅读许可协议 &#xff08;3&#xff09;选择安装路径 &#xff08;4&#xff09;选择组件 &#xff08;5&#xff09;选择开始菜单文件夹…...

关系数据库设计理论

目录 一、数据依赖——重点 &#xff08;1&#xff09;平凡依赖/非平凡函数依赖 &#xff08;2&#xff09;完全/部分函数依赖 &#xff08;3&#xff09;传递函数依赖 二、范式&#xff08;NF&#xff09; &#xff08;1&#xff09;第一范式 &#xff08;2&#xff09…...

图解LLM智能体(LLM Agents):构建与运作机制的全面解析

LLM智能体:构建与运作机制 LLM智能体(LLM Agents)正在迅速普及,似乎逐渐取代了我们熟悉的传统对话式LLM。这些令人惊叹的能力并非凭空而来,而是需要多个组件协同工作。 本文包含超过60张定制插图,将深入探讨LLM智能体的领域、其核心组件以及多智能体框架的工作原理。 文…...

Anaconda 入门指南

Anaconda 入门指南 一、下载安装 Anaconda 1、下载地址&#xff1a;Anaconda 推荐下载 python3 版本, 毕竟未来 python2 是要停止维护的。 2、安装 Anaconda 按照安装程序提示一步步安装就好了, 安装完成之后会多几个应用&#xff1a; Anaconda Navigtor &#xff1a;用于管…...

YOLOv11小白的进击之路(九)创新YOLO11损失函数之NWD损失函数源码解读

之前的博客也有对YOLO11的损失函数进行过源码分析&#xff0c;可以参考&#xff1a;YOLOv11小白的进击之路&#xff08;六&#xff09;创新YOLO的iou及损失函数时的源码分析_yolov11的损失函数是什么-CSDN博客最近在做小目标检测的时候注意到了NWD损失函数&#xff0c;这里对其…...

【c++】内存序 和 内存一致性模型

c 11 中为了支持并发&#xff0c;定义了内存序和内存一致性模型。这个概念听起来非常高深&#xff0c;好像是在多线程编程领域浸淫多年之后的神级程序员才能搞明白&#xff0c;并用明白的东西。 本文尝试用最简单的方式说清楚这个概念。因为这个概念真的超级简单&#xff0c;大…...

力扣128. 最长连续序列 || 452. 用最少数量的箭引爆气球

最长连续列 给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 输入&#xff1a;nums [100,4,200,1,3,2] 输出&#xff1a;4 解释&…...

从零开始写C++3D游戏引擎(开发环境VS2022+OpenGL)之十一点二五 光照贴图(lighting maps)的实现 细嚼慢咽逐条读代码系列

写在篇前的话 作为一个曾经在代码堆里面苦苦挣扎的萌新,困惑的事情在于库,各种依赖,包换文件,链接库,纠结于代码的作用意义。尤其在3D引擎开发的问题上,很多人都被各种困难给阻拦,放弃了在3D渲染,3D游戏引擎上大涨鸿图的机会。 当然关于3D游戏引擎的教程已经汗牛充栋…...

优先级队列(PriorityQueue)_1_模拟实现优先级队列

1、概念 前面介绍过队列&#xff0c;队列是一种先进先出(FIFO)的数据结构 &#xff0c;但有些情况下&#xff0c; 操作的数据可能带有优先级&#xff0c;一般出队 列时&#xff0c;可能需要优先级高的元素先出队列 &#xff0c;这时候&#xff0c;使用队列显然不合适了。 在这种…...

java后端怎么写好根据角色控制查询不同数据,

z总的思路&#xff0c;先把不带查询条件的包含角色控制场景&#xff08;比如&#xff1a;总公司经理角色可以查看所有数据&#xff0c;但是暂存的话只能查自己暂存的&#xff0c;分公司&#xff0c;只能查自己所属分公司的&#xff0c;&#xff09;的所有数据查出来 例如查询的…...

《量子比特:AI复杂算法破局的关键力量》

在科技飞速发展的今天&#xff0c;人工智能&#xff08;AI&#xff09;与量子计算成为了推动人类进步的两大引擎。而量子比特&#xff0c;作为量子计算的基石&#xff0c;正逐渐展现出其在实现复杂AI算法时相较于传统比特的独特优势&#xff0c;为AI领域带来了前所未有的变革潜…...

MVC_Publish-Subscriber 模式中的事件处理程序

MVC_Publish-Subscriber 模式中的事件处理程序 MVC 中的事件处理&#xff1a;发布者-订阅者模式 程序启动时&#xff0c;controlRecipes将被传入addHandlerRender; addHandlerRender会侦听事件&#xff08;addEventListener&#xff09;,并使用controlRecipes作为回调&#xf…...

RxSwift 学习笔记第四篇之RxSwift在项目中的简单应用

目录 前言 一、RxCocoa在项目中的用法 1.Target Action 2.代理 3.闭包回调 4.通知 二、一个计时器的例子 前言 在上面的两篇文章中,我们了解到了RxSwift中的Observable和Observer,本篇文章我们主要介绍下RxSwift项目中的使用。 一、RxCocoa在项目中的用法 RxCocoa 给 …...

Java面试黄金宝典2

1. 什么是 Concurrent 包 java.util.concurrent&#xff08;简称 Concurrent 包&#xff09;是 Java 5 引入的一个用于并发编程的工具包。它提供了一系列用于处理多线程编程的类和接口&#xff0c;帮助开发者更方便、安全地进行并发编程。 原理 该包基于 Java 的多线程机制和锁…...

【在数轴上找最优位置,使移动距离最短】

L1-4 破碎的心&#xff0c;无法挽回的距离 题目描述: YFffffff 最近在感情上遭受了失败&#xff0c;他的心也破碎成了n块碎片&#xff0c;散落在了数轴上的 n 个位置。 你是一个情感修复师&#xff0c;作为 YFffffff 的好友&#xff0c;你试图将这些破碎的心重新聚集到一个位…...

3D标定中的平面约束-平面方程的几何意义

平面方程的一般形式为 AxByCzD0&#xff0c;其中系数 A、B、C、D共同决定了平面的几何特性。 系数对平面姿态的影响 1. 法向量方向2. 平面位置3. 比例关系4. 姿态变换5.平面空间变换 1. 法向量方向 法向量方向由 A、B、C 决定 核心作用&#xff1a;系数 A、B、C 构成的向量 (…...

singleInstance 和 singleTask的 重要 区别

singleInstance 和 singleTask 是 Android 中 Activity 的两种启动模式&#xff0c;它们主要用于控制 Activity 在任务栈中的行为。以下是两者的区别&#xff1a; 1. singleTask 定义: 每个 singleTask 模式的 Activity 在一个任务栈中只会存在一个实例。行为: 如果该 Activi…...

【如何在OpenWebUI中使用FLUX绘画:基于硅基流动免费API的完整指南】

如何在OpenWebUI中使用FLUX绘画&#xff1a;基于硅基流动免费API的完整指南 注册并获取硅基流动秘钥OpenWebUI中使用函数配置自定义模型-提示词配置效果验证 ) FLUX绘画是一种强大的AI绘图工具&#xff0c;本文将详细介绍如何在OpenWebUI中集成并使用FLUX绘画功能&#xff0c;…...

【Linux】浅谈环境变量和进程地址空间

一、环境变量 基本概念 环境变量&#xff08;Environment Variables&#xff09;是操作系统提供的一种机制&#xff0c;用于存储和传递配置信息、系统参数、用户偏好设置等。 环境变量的作用 配置程序行为&#xff1a; 程序可以通过环境变量获取配置信息&#xff0c;例如日…...

vue数字公式篇(一)

一、使用插件来创造数字公式 因为只是展示和编辑 我看这个公式挺多&#xff0c;也对公式不太了解所以就这样&#xff0c;开始我的代码展示了 1、安装mathlive cnpm install mathlive2、页面 <template><div><label>输入 LaTeX 公式:</label><div …...

基于PMU的14节点、30节点电力系统状态估计MATLAB程序

“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 程序简介&#xff1a; 程序采用三种方法对14节点和30节点电力系统状态进行评估&#xff1a; ①PMU同步向量测量单元结合加权最小二乘法&#xff08;WLS&#xff09;分析电力系统的电压幅值和相角状态&#xff1b; …...

5 分钟用满血 DeepSeek R1 搭建个人 AI 知识库(含本地部署)

最近很多朋友都在问&#xff1a;怎么本地部署 DeepSeek 搭建个人知识库。 老实说&#xff0c;如果你不是为了研究技术&#xff0c;或者确实需要保护涉密数据&#xff0c;我真不建议去折腾本地部署。 为什么呢&#xff1f; 目前 Ollama 从 1.5B 到 70B 都只是把 R1 的推理能力…...

QT QML实现音频波形图进度条,可点击定位或拖动进度

前言 本项目实现了使用QT QML创建一个音频波形图进度条的功能。用户可以在界面上看到音频波形图&#xff0c;并且可以点击进度条上的位置进行定位&#xff0c;也可以拖动进度条来调整播放进度。可以让用户更方便地控制音频的播放进度&#xff0c;并且通过音频波形图可以直观地…...

浅谈StarRocks SQL性能检查与调优

StarRocks性能受数据建模、查询设计及资源配置核心影响。分桶键选择直接决定数据分布与Shuffle效率&#xff0c;物化视图可预计算复杂逻辑。执行计划需关注分区裁剪、谓词下推及Join策略&#xff0c;避免全表扫描或数据倾斜。资源层面&#xff0c;需平衡并行度、内存限制与网络…...

味觉传送器E-Taste:开启虚拟世界的味觉之门

味觉传送器E-Taste&#xff1a;开启虚拟世界的味觉之门 一、发明背景与动机 随着虚拟现实&#xff08;VR&#xff09;和增强现实&#xff08;AR&#xff09;技术的飞速发展&#xff0c;人们在虚拟世界中的沉浸感不断提升&#xff0c;视觉和听觉体验已经取得了显著的突破。然而…...

ISE 14.7 IP核 Block Memory Generator 更换coe

ISE 14.7 IP核 Block Memory Generator 更换coe 打开XCO 后缀&#xff0c;修改下面的coe_file 目录&#xff0c;并且重新regenerate ip 核即可...

【Auto-Scroll-List 组件设计与实现分析】

Auto-Scroll-List 组件设计与实现分析 gitee代码仓库 https://gitee.com/chennaiyuan/dayup-record/tree/master/%E4%B8%80%E4%BA%9B%E7%BB%84%E4%BB%B6/auto-scroll-list 1. 组件概述 我们封装的 AutoScrollList 是一个自动滚动列表组件&#xff0c;主要用于展示需要自动循…...

用hexo初始化博客执行hexo init时碰到的问题

用hexo初始化博客执行hexo init时碰到的问题 $ hexo init myblog INFO Cloning hexo-starter https://github.com/hexojs/hexo-starter.git fatal: unable to access https://github.com/hexojs/hexo-starter.git/: SSL certificate problem: unable to get local issuer cer…...