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

Spring 学习源码的基础 核心原理与核心概念

文章目录

  • 核心原理
    • AnnotationConfigApplicationContext
    • IoC 容器加载流程
    • Spring 中如何创建一个对象
    • Bean 的创建过程 (生命周期)
    • 单例 原型
    • 推断构造方法
    • 依赖注入
    • AOP 动态代理
    • 判断是否需要 AOP 的大致流程
    • CGLib 做 AOP 的大致流程
    • 事务
    • 事务代理对象执行方法的流程
    • 事务注解排至失效的原因
    • 为何下方加了 @Configuration 事务才能生效
  • 核心概念
    • BeanDefinition
    • BeanDefinitionReader
      • AnnotatedBeanDefinitionReader
      • XmlBeanDefinitionReader
      • ClassPathBeanDefinitionScanner
    • BeanFactory
      • DefaultListableBeanFactory
      • ApplicationContext
        • AnnotationConfigApplicationContext
        • ClassPathXmlApplicationContext
        • 国际化 MessageSource


核心原理

AnnotationConfigApplicationContext

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) context.getBean("userService");
userService.test();
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = (UserService) context.getBean("userService");
userService.test();

我们很少按照上面的方式使用 Spring, 而是使用 Spring MVC, 或者 Spring Boot, 但是它们本质上都是基于这种方式的, 都需要在内部去创建一个 ApplicationContext

  • SpringBoot 创建的是 AnnotationConfigApplicationContext
  • SpringMVC 创建的是 XmlWebApplicationContext, 和 ClassPathXmlApplicationContext 类似都是基于 xml 的

AnnotationConfigApplicationContext 是研究学习的主类

IoC 容器加载流程

IoC容器加载流程可以分成两个步骤

  • 准备, 注册一些底层基础架构工具类, 在容器初始化流程中使用, 然后注册配置类, 然后刷新容器
  • 扫描, 将配置的各种 Bean 解析成为 BeanDefinition, 存入 BeanDefinitionMap
  • 遍历 BeanDefinitionMap, 生产单例, 并缓存到单例池 singletonObjects

Spring 中如何创建一个对象

new AnnotationConfigApplicationContext(Config.class) 的过程就是 IoC 容器的加载流程, 扫描生成 BeanDefinition, 遍历生成单例 Bean. 最后人为调用 getBean(beanName) 去缓存中拿到对应的 Bean

Bean 的创建过程 (生命周期)

class -> 反射newInstance -> 原始对象 -> 依赖注入(属性赋值) -> 一堆Aware -> 初始化前(@PostConstruct) -> 初始化(InitailizedBean) -> 初始化后(AOP) -> 代理对象(代理对象.target=原始对象) -> Bean

  • 实例化, 通过反射调用类的某个构造方法创建对象, 如果有多个构造方法, 会进行选择, 叫做推断构造方法
  • 依赖注入(属性赋值), 遍历对象内的字段, 有 @Autowired 的自动赋值
  • Aware 织入, 判断对象是否是(即类是否实现了) BeanNameAware, ApplicationContextAware 等各种 Aware, 是的话就强转调用结构定义的 set 方法
  • @PostConstruct 处理, 判断是否有方法有该注解, 有的话则执行该方法
  • InitializingBean 处理, 判断对象是否是该接口的实例, 是的话则执行接口定义的 afterPropertiesSet 方法
  • 自定义的 init-method 方法
  • 判断是否需要 AOP, 不需要时返回当前对象, 需要时则生成代理对象, 并返回
  • 如果是单例 Bean 则存入单例池

单例 原型

Bean 的作用域分为单例和原型两种

  • 单例: 每次 getBean 拿到的都是同一个对象, 首次创建后就会缓存到单例池
  • 原型: 每次 getBean 都会重新创建一次, 不会放到单例池

懒加载的 Bean 在 IoC 容器加载时不会被创建和缓存, 在使用时才会创建和缓存

推断构造方法

实例化时默认使用无参构造器(写了有参默认就没有无参了, 除非显式定义)

有无参构造器就使用无参构造器, 没无参构造器则判断有几个有参构造器, 只有一个的话就使用这一个有参构造器, 有多个的话因为不能确认使用哪个, 所以报错找不到默认无参构造器

有多个有参构造器的话, 也可以加 @Autowired 来指定使用哪个有参构造器

有参构造器的参数对象哪里来?

  • 先根据类型到容器中找, 如果只有一个则直接使用, 如果有多个则根据名称来过滤, 如果又匹配名称的则直接使用, 如果没有匹配的, 则报错

依赖注入

先按类型到容器中过滤, 匹配的如果只有一个则直接使用, 多个则再按名称匹配, 有匹配到的直接使用, 没有则报错

AOP 动态代理

在创建 Bean 的最后一步, 会判断是否需要做 AOP, 需要则做动态代理

判断是否需要 AOP 的大致流程

  • 找出所有切面 Bean
  • 遍历其中每个方法, 判断是否写了 @Before, @After 等注解
  • 如果写了, 则判断其所对应的 PointCut 和当前创建的 Bean 是否匹配
  • 如果匹配, 则说明当前 Bean 需要做 AOP

CGLib 做 AOP 的大致流程

  • 生成继承原类的代理类, 代理类持有原类对象 target. 注意, 原类对象是经过 Bean 创建流程的, 包括依赖注入, 初始化等流程
  • 代理类中覆盖原类中的方法, 最终会调用到 target 的对应方法, 但是会在前后把切面逻辑都加上, 大致如下
  • 最后创建 Bean 返回的是持有原始对象的代理对象
public class UserService {@Autowiredprivate OrderService orderService;public void test() {sout;}
}
class UserServiceProxy extend UserService {UserService target;public void test() {// @Before 的逻辑target.test();// @After 的逻辑}
}

代理类继承自原始类, 所以原始类的字段在代理类中也有, 但是 Spring 并不会为代理类做依赖注入, 因为没有必要

代理对象仅仅用于强化原始对象的某方法, 如果在切面逻辑中需要用到原始对象的依赖注入的字段, 也可以通过 JoinPoint.getTarget() 拿到原始对象来操作, 而原始对象中各字段已经做过依赖注入了

事务

某方法添加了 @Transactional 注解后, 会在 AOP 阶段给本类生成代理类和代理对象

事务代理对象执行方法的流程

  • 判断当前方法上有没有 @Transactional 注解
  • 有的话由事务管理器创建一个数据库连接 (此连接不是来自连接池?)
  • 设置连接的 autoCommit 为 false (无事务注解时, 连接是从连接池获取, 每执行一条 SQL 自动提交一次)
  • 执行方法, 执行方法中的 SQL
  • 调用连接的提交或回滚方法

事务注解排至失效的原因

事务是否会失效, 就看执行 @Transactional 注解方法的是哪个对象

  • 代理对象: 不会失效
  • 原始对象: 失效, 因为执行的就是普通方法, 没有代理对象做的强化了

最常见的例子, 类中有两个事务方法 a 和 b, 而 a 中会调用 b, 单独执行 a 和 b 事务都不会失效, 但是在 a 中执行 b 时, b 的事务注解上的配置会失效

因为执行 a 的流程是这样的, 拿到类的代理对象, 执行其 a, 先走切面逻辑, 创建连接, 设置不自动提交, 然后才执行 target.a 即原始对象的 a 方法, 此时的主体是原始对象而非代理对象. 执行到 b 方法时, 本质是 this.b, 主体还是原始对象, 并没有切面逻辑, 所以在 a 里面的 b 方法的事务注解配置都会失效

当然还有很多其他原因, 需要具体分析

其他的 AOP 失效很多也是一样的原因, 都是自调用导致的

有解决办法, 就是自引用, 类中依赖注入自身 self, 此时的 self 是代理对象, 在 a 中调用 b 的时候, 用 self.b, 这样主体是代理对象, 有切面强化逻辑, b 的事务配置就会生效了

为何下方加了 @Configuration 事务才能生效

@Configuration
public class Config {@Beanpublic TransactionManager transationManager() {return new DataSourceTransactionManager(dataSource());}@Beanpublic JdbcTemplate jdbcTemplate() {return new JdbcTemplate(dataSource())}@Beanpublic DataSource dataSource() {return new DataSource();}
}
  • 不加时, 调用两次 dataSource() 生成两个不同的数据源, 最终事务管理器和模板使用了不同的数据源
  • 加时, 会有特殊的处理, dataSource() 会被认为是一个 Bean, 传入两者的是同一个对象

在 JdbcTemplate 中获取连接时, 会检查当前是否为事务环境, 是的话会从 TransactionSynchronizationManager.getResource(dataSource); 中获取线程绑定的连接, 即事务管理器创建的那个连接, 需要使用同一个数据源对象才能拿到同一个连接, 这样事务管理器的提交和回滚操作才会对 JdbcTemplate 生效

核心概念

Spring 源码里有很多抽象和工具, 需要提前有一定了解, 读源码时能轻松一些

BeanDefinition

BeanDefinition 用来记录 Bean 配置的各种信息

  • class,表示Bean类型
  • scope,表示Bean作用域,单例或原型等
  • lazyInit:表示Bean是否是懒加载
  • initMethodName:表示Bean初始化时要执行的方法
  • destroyMethodName:表示Bean销毁时要执行的方法
  • 还有很多…

定义 Bean 的方式有申明式和编程式两种, 通过各种方式定义的 Bean 最终都会被解析为 BeanDefinition 并缓存起来

  • 申明式:
    • < bean/>
    • @Bean
    • @Component(@Service,@Controller)
  • 编程式
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);// 生成一个BeanDefinition对象,并设置beanClass为User.class,并注册到ApplicationContext中
    AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
    beanDefinition.setBeanClass(User.class);
    context.registerBeanDefinition("user", beanDefinition);System.out.println(context.getBean("user"));
    

BeanDefinitionReader

用于根据某些规则将资源解析成为 BeanDefinition

AnnotatedBeanDefinitionReader

可以将某个类解析成为 BeanDefinition, 包括类上的注解(@Conditional,@Scope、@Lazy、@Primary、@DependsOn、@Role、@Description)

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(context);// 将User.class解析为BeanDefinition
reader.register(User.class);System.out.println(context.getBean("user"));

XmlBeanDefinitionReader

可以解析 < bean/> 标签配置的 Bean

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(context);
int i = reader.loadBeanDefinitions("spring.xml");System.out.println(context.getBean("user"));

ClassPathBeanDefinitionScanner

扫描器, 但是它的作用和 BeanDefinitionReader 类似, 它可以进行扫描, 扫描某个包路径, 对扫描到的类进行解析

如果扫描到的类上存在 @Component 注解, 那么就会把这个类解析为一个 BeanDefinition

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.refresh();ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.scan("com.coder");System.out.println(context.getBean("userService"));

BeanFactory

Spring 容器的根接口, Bean 工厂, 负责创建 Bean 和获取 Bean, 提供各种 getBean() 方法的定义

DefaultListableBeanFactory

BeanFactory 有一个最核心的实现类 DefaultListableBeanFactory, 可以直接当作 BeanFactory 来使用, 可以替代 ApplicationContext 来使用, 就是功能会少一点而已

DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(User.class);beanFactory.registerBeanDefinition("user", beanDefinition);System.out.println(beanFactory.getBean("user"));

DefaultListableBeanFactory

DefaultListableBeanFactory 的架构体系如上, 有很多接口(能力)和类

  • AliasRegistry: 支持别名功能, 定义了 alias 的注册/获取/判断/移除等功能, 在这里支持一个 BeanDefinition / Bean 有多个名称的功能
  • SimpleAliasRegistry, 维护着 Map<String, String> aliasMap, 在这里是 alias 与 beanName 的多对一关系, 便于从别名找到原名(别名也能起别名), 当然也可以从原名找到所有别名
  • BeanDefinitionRegistry: 定义了 BeanDefinition 的注册/获取/存在/移除等功能
  • SingletonBeanRegistry: 定义了单例 Bean 的注册/存在/获取/获取数量/获取名称等功能
  • BeanFactory: 定义了 Bean 的获取/存在/获取别名/判断作用域等功能
  • ListableBeanFactory: 扩展了 BeanFactory, 提供了方法用于枚举和检索容器中的 bean 实例, 可以方便地获取所有 bean 的名称、按类型获取 bean、按条件检索 bean 等操作
  • HierarchicalBeanFactory: 扩展了 BeanFactory, 提供了层次化的容器结构和继承机制, 每个子容器可以独立管理自己的 bean 定义和实例。子容器可以继承父容器中定义的 bean,并可以在子容器中覆盖或扩展父容器中的 bean 定义。可以实现更好的模块化和组织化,并灵活管理和定制 bean 的定义和作用域
  • AutowireCapableBeanFactory: 扩展了 BeanFactory, 提供了自动装配 bean 的能力, 可以实现依赖注入、自动装配和解耦等功能
  • ConfigurableBeanFactory, 除了 BeanFactory Bean 之外,还提供用于配置 BeanFactory 的工具. 添加了设置父BeanFactory、类加载器(表示可以指定某个类加载器进行类的加载)、设置Spring EL表达式解析器(表示该BeanFactory可以解析EL表达式)、设置类型转化服务(表示该BeanFactory可以进行类型转化)、可以添加BeanPostProcessor(表示该BeanFactory支持Bean的后置处理器),可以合并BeanDefinition,可以销毁某个Bean等等功能
  • ConfigurableListableBeanFactory: 除了 ConfigurableBeanFactory 之外, 它还提供了分析和修改 Bean 定义以及预实例化单例的工具
  • DefaultSingletonBeanRegistry: 主要用于管理和维护单例 bean 的注册和获取, singletonObjects 在这里
  • FactoryBeanRegistrySupport: 主要用于支持 FactoryBean 的注册和获取, factoryBeanObjectCache 在这里
  • AbstractBeanFactory: 功能已经很全面了, 但是不能自动装配和获取 beanNames, beanPostProcessors 在这里
  • AbstractAutowireCapableBeanFactory: 拥有了自动装配的功能
  • DefaultListableBeanFactory: 是 Spring 容器的一个关键组件,负责管理 BeanDefinition 的注册、合并和查找,以及 Bean 的创建、装配和销毁。它提供了丰富的功能和灵活的配置选项,是 Spring 应用程序中常用的 BeanFactory 实现之一, beanDefinitionMap 在这里

ApplicationContext

BeanFactory 有一个最核心的子接口 ApplicationContext, 其定义如下

public interface ApplicationContext 
extends EnvironmentCapable, 
ListableBeanFactory, 
HierarchicalBeanFactory, 
MessageSource, 
ApplicationEventPublisher, 
ResourcePatternResolver

在这里插入图片描述

  • HierarchicalBeanFactory:拥有获取父BeanFactory的功能
  • ListableBeanFactory:拥有获取beanNames的功能
  • ResourcePatternResolver:资源加载器,可以一次性获取多个资源(文件资源等等)
  • EnvironmentCapable:可以获取运行时环境(没有设置运行时环境功能)
  • ApplicationEventPublisher:拥有广播事件的功能(没有添加事件监听器的功能)
  • MessageSource:拥有国际化功能

ApplicationContext 的定位是 Spring 的应用上下文, 负责管理和组织应用程序的各个部分. 从代码层面来说, ApplicationContext 是一个 BeanFactory, 从架构层面来说, ApplicationContext 是比 BeanFactory 更加高级的存在, 它统御 BeanFactory, EnvironmentCapable, MessageSource 等这些组件完成相应的功能, BeanFactory 只是它的一个零件而已

照着这个思路来看, GenericApplicationContext 不继承 DefaultListableBeanFactory 而是将之作为一个属性, 从 BeanFactory 继承来的功能全部委托其持有的 DefaultListableBeanFactory 来执行, 就是非常合理的事情了

ApplicationContext 接口继承了 ListableBeanFactory 和 HierarchicalBeanFactory, 但它的定位是一个高位 BeanFactory, 只是聚焦于 BeanFactory 一定程度的基础功能即可, 并不需要中低层更强大的更加细节的全部功能

ApplicationContext 有两个重要的实现类

  • AnnotationConfigApplicationContext
  • ClassPathXmlApplicationContext

AnnotationConfigApplicationContext

在这里插入图片描述

  • Lifecycle: 定义启动/停止生命周期控制方法的通用接口
  • ConfigurableApplicationContext: 增加了,添加事件监听器、添加BeanFactoryPostProcessor、设置Environment,获取ConfigurableListableBeanFactory等功能
  • AbstractApplicationContext: 实现通用上下文功能, 大名鼎鼎的 refresh 方法就在这里了
  • GenericApplicationContext: 通用的应用上下文具体实现类
  • AnnotationConfigRegistry: 用于注释配置应用程序上下文, 可以单独注册某个类为 BeanDefinition(可以处理该类上的 @Configuration @Bean 注解)
  • AnnotationConfigApplicationContext: 是一种方便且强大的应用上下文实现,适用于注解驱动的开发方式。它通过扫描和处理注解,实现了自动化的 Bean 注册和装配,减少了繁琐的 XML 配置

ClassPathXmlApplicationContext

在这里插入图片描述
同样继承了 AbstractApplicationContext,但是相对于AnnotationConfigApplicationContext 而言,功能没有AnnotationConfigApplicationContext 强大,比如不能注册 BeanDefinition

国际化 MessageSource

相关文章:

Spring 学习源码的基础 核心原理与核心概念

文章目录 核心原理AnnotationConfigApplicationContextIoC 容器加载流程Spring 中如何创建一个对象Bean 的创建过程 (生命周期)单例 原型推断构造方法依赖注入AOP 动态代理判断是否需要 AOP 的大致流程CGLib 做 AOP 的大致流程事务事务代理对象执行方法的流程事务注解排至失效的…...

cpolar做一个内网穿透

因为不在公司&#xff0c;需要访问公司的数据库&#xff0c;所以做一个内网穿透 下载安装 下载地址&#xff1a; https://dashboard.cpolar.com/get-started 下载后是个压缩包&#xff0c;解压后傻瓜式安装 操作隧道 安装后打开Cpolar Web UI 登录账号&#xff0c;查看隧…...

自动驾驶——最优控制算法(LQR)工程化总结

1. Summary 时隔一年&#xff0c;从写下第一篇博文自动驾驶-LQR工程实现&#xff08;调研&#xff09;&#xff0c;到近段时间&#xff0c;真正在我们的控制器上运行最优控制算法&#xff08;LQR&#xff09;&#xff0c;一步一个脚印&#xff0c;从开始只是知道其“控制理论”…...

【微服务】05-网关与BFF(Backend For Frontend)

文章目录 1.打造网关1.1 简介1.2 连接模式1.3 打造网关 2.身份认证与授权2.1 身份认证方案2.1.1 JWT是什么2.1.2 启用JwtBearer身份认证2.1.3 配置身份认证2.1.4 JWT注意事项 1.打造网关 1.1 简介 BFF(Backend For Frontend)负责认证授权&#xff0c;服务聚合&#xff0c;目标…...

保证MQ的高可用的几种方案

推荐阅读 AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 资源分享 史上最全文档AI绘画stablediffusion资料分享 AI绘画关于SD,MJ,GPT,SDXL百科全书 「java、python面试题」…...

MySql013——函数

一、数据处理函数 1.1、文本处理函数 函 数 说 明 Left() 返回串左边的字符Length() 返回串的长度Locate() 找出串的一个子串Lower() 将串转换为小写LTrim() 去掉串左边的空格Right() 返回串右边的字符RTrim() 去掉串右边的空格Soundex() 返回串…...

k8s-dashboard使用指导手册

一、访问 dashboard http://172.66.209.101:32001 二、选择 Namespace 如下图&#xff1a; 1 在①搜索框中输入 spms 2 在②选择 spms-cloud 三、查找 pod 1 打开 pod 列表 2 打开过滤窗口 3 搜索 pod 在打开的搜索框中输入 pod的关键字&#xff0c;支持模糊搜索 如搜索…...

Python爬虫快速入门指南

引言&#xff1a; 网络爬虫是一种自动化程序&#xff0c;可以在互联网上搜集和提取数据。Python作为一种功能强大且易学的编程语言&#xff0c;成为了许多爬虫开发者的首选。本文将为你提供一个关于Python爬虫的快速入门指南&#xff0c;包括基本概念、工具和实际案例。 第一…...

Java人脸识别技术探索与实践

人脸识别技术作为生物特征识别领域的一项重要应用&#xff0c;近年来在安全、便捷以及科研等方面取得了显著的进展。在Java编程领域&#xff0c;人脸识别也得到了广泛的关注和应用。本文将介绍Java中人脸识别技术的基本概念、常用库以及实际示例代码&#xff0c;带您深入了解这…...

【鞋服零售ERP】之要货申请单设计思路

引言 要货申请单在本系统中也是一张较为核心的单据&#xff0c;整体的思路是将其池化&#xff0c;解决收发货方业务简化&#xff0c;账务处理逻辑化的设计理念。首先鞋服零售ERP就是基于多组织的业务架构&#xff0c;多销售组织和店铺属性&#xff1b;其次是在零售如何在业处处…...

EWM怎么取消pinking,SAP_EWM取消拣配报错处理方式

EWM是SAP的一个模块&#xff0c;代表扩展仓库管理&#xff08;Extended Warehouse Management&#xff09;&#xff0c;是SAP企业资源计划&#xff08;ERP&#xff09;的一部分。它提供了一个完整的、高级的仓库管理解决方案&#xff0c;支持企业在全球范围内的仓库管理、订单管…...

TensorFlow 的基本概念和使用场景

TensorFlow 是 Google 开源的机器学习框架&#xff0c;它支持使用数据流图&#xff08;Data Flow Graph&#xff09;的方式进行计算&#xff0c;以实现大规模分布式机器学习应用。TensorFlow 在深度学习、自然语言处理、计算机视觉等领域有广泛应用。 TensorFlow 中的重要概念…...

openssl 加密(encrypt)、解密(decrypt)、签名(sign)、验证(verify)

一、使用openssl rsautl 进行加密、解密、签名、验证 [kyzjjyyzc-zjjcs04 openssl]$ openssl rsautl --help Usage: rsautl [options] -in file input file -out file output file -inkey file input key -keyform arg private key format - default PEM …...

视频云存储/安防监控视频AI智能分析网关V3:抽烟/打电话功能详解

人工智能技术已经越来越多地融入到视频监控领域中&#xff0c;近期我们也发布了基于AI智能视频云存储/安防监控视频AI智能分析平台的众多新功能&#xff0c;该平台内置多种AI算法&#xff0c;可对实时视频中的人脸、人体、物体等进行检测、跟踪与抓拍&#xff0c;支持口罩佩戴检…...

新版Jadx 加载dex报错 jadx.plugins.input.dex.DexException:Bad checksum 解决方法

本文所有教程及源码、软件仅为技术研究。不涉及计算机信息系统功能的删除、修改、增加、干扰,更不会影响计算机信息系统的正常运行。不得将代码用于非法用途,如侵立删!新版Jadx(1.6+) 加载dex报错 jadx.plugins.input.dex.DexException:Bad checksum 解决方法 环境 win10J…...

win11+vmware17+centos7.9环境搭建

温故知新 &#x1f4da;第一章 前言&#x1f4d7;背景&#x1f4d7;目标&#x1f4d7;总体方向 &#x1f4da;第二章 安装部署环境&#x1f4d7;安装VMware Workstation 17 Pro软件&#x1f4d7;安装CentOS-7虚拟机&#x1f4d5;镜像下载地址&#x1f4d5;创建虚拟机&#x1f4…...

Unity Meta Quest MR 开发教程:(二)自定义透视 Passthrough【透视功能进阶】

文章目录 &#x1f4d5;教程说明&#x1f4d5;动态开启和关闭透视⭐方法一&#xff1a;OVRManager.instance.isInsightPassthroughEnabled⭐方法二&#xff1a;OVRPassthroughLayer 脚本中的 hidden 变量 &#x1f4d5;透视风格 Passthrough Styling⭐Inspector 面板控制⭐代码…...

vue3学习源码笔记(小白入门系列)------ 组件是如何渲染成dom挂载到指定位置的?

文章目录 os准备组件如何被挂载到页面上第一步 createApp 做了哪些工作&#xff1f;ensureRendererbaseCreateRenderercreateAppAPImountrenderpatchprocessComponentprocessElement 总结 os 学习一下vue3 源码&#xff0c;顺便记录分享下 使用vitest 插件调试源码 辅助阅读 …...

【编码规范】从代码之丑聊代码规范

最近看了代码之丑&#xff0c;就打算整理下&#xff0c;总结一下。 代码命名 首先从命名来说的话&#xff0c;其实对于大多数程序员来说&#xff0c;可能基本都是翻译软件翻译下&#xff0c;然后就直接改成对应的类名、参数名、函数名等。其实仔细一想&#xff0c;命名其实是…...

pytorch中的register_buffer

今天在一个模型的init中遇到了self.register_buffer(‘running_mean’, torch.zeros(num_features)) register_buffer(self, name, tensor)是一个PyTorch中的方法&#xff0c;它的作用是向模块&#xff08;module&#xff09;中添加一个持久的缓冲区&#xff08;buffer&#xf…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...