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

从getBean()分析BeanFactory和ApplicationContext

本文说了哪些问题:

  • BeanFactory 是啥
  • ApplicationContext 是啥
  • 什么时候去实例化一个 bean, BeanFactory 和 ApplicationContext 实例化 bean 都是在什么时候

一个 Bean 什么时候被初始化

任何一个 Bean, 都是在 getBean () 的时候被初始化的.BeanFactory 需要字节手动调用 getbean 获取才会创建, 而 ApplicationContext 则是使用
那为什么还要区分 BeanFactory 呢?
这是因为 BeanFactory 初始化有这几个阶段

Resource resource = new ClassPathResource("applicationContext.xml");
// 创建一个DefaultListableBeanFactory
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
BeanDefinitionReader beanDefinitionReader = new 
// 创建XmlBeanDefinitonReder
XmlBeanDefinitionReader(defaultListableBeanFactory);
// loadBeanDefiniton
beanDefinitionReader.loadBeanDefinitions(resource);
本文不过多解释其他不重要的知识点, 着重于**文章题目**的解释

观点纠正:
注意了, loadBeanDefintions 方法并不会去实例化 Bean, 这里只是把我们定义的 Bean 的信息, 封装成 BeanDefiniton 而已, 并不会去实例化.

对于创建 Bean, 在 beanFactory 中, 则是以我们手动调用 getBean 为准, 才会去创建 Bean

很多时候, 我们使用 Spring 的时候, 并没有去手动的创建, bean 也都存在了啊??
这是什么情况.
这是因为 ApplicationContext 的预加载机制, 会加载所有的单例的非抽象的以及非懒加载的 Bean

看见懒加载, 那么懒加载的 bean 啥时候加载?? 还是 getBean.
然后你再猜猜预加载机制是通过什么方法来进行预加载的??
还是 getBean ()方法

先来看看 ClassPathXmlAplicationContext 的注释, ClassPathXmlApplicationContext 在容器初始化的时候, 就调用了父类的 refersh ()方法, 然后在其中的 finishBeanFactoryInitialization(beanFactory) 方法 ----> 调用了 beanFactory.preInstantiateSingletons(); 这一行关键代码

	public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);// 创建出所有的单实例Bean;Trigger initialization of all non-lazy singleton beans...for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //开始解析文件的时候每一个bean标签被解析封装成一个BeanDefinitionif (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) { //如果是FactoryBean则执行下面逻辑Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); //得到HelloFactoryif (bean instanceof FactoryBean) {FactoryBean<?> factory = (FactoryBean<?>) bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else { //不是FactoryBean则执行这个,普通的单实例非懒加载bean的创建getBean(beanName); //}}}// 触发 post-initialization 逻辑;  Trigger post-initialization callback for all applicable beans...for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {smartSingleton.afterSingletonsInstantiated();return null;}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}smartInitialize.end();}}}public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);// 创建出所有的单实例Bean;Trigger initialization of all non-lazy singleton beans...for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //开始解析文件的时候每一个bean标签被解析封装成一个BeanDefinitionif (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) { //如果是FactoryBean则执行下面逻辑// FACTORY_BEAN_PREFIX == '&'Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); //得到HelloFactoryif (bean instanceof FactoryBean) {FactoryBean<?> factory = (FactoryBean<?>) bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else { //不是FactoryBean则执行这个,普通的单实例非懒加载bean的创建getBean(beanName); //}}}// 触发 post-initialization 逻辑;  Trigger post-initialization callback for all applicable beans...for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {smartSingleton.afterSingletonsInstantiated();return null;}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}smartInitialize.end();}}}public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);// 创建出所有的单实例Bean;Trigger initialization of all non-lazy singleton beans...for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //开始解析文件的时候每一个bean标签被解析封装成一个BeanDefinitionif (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) { //如果是FactoryBean则执行下面逻辑Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); //得到HelloFactoryif (bean instanceof FactoryBean) {FactoryBean<?> factory = (FactoryBean<?>) bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else { //不是FactoryBean则执行这个,普通的单实例非懒加载bean的创建getBean(beanName); //}}}// 触发 post-initialization 逻辑;  Trigger post-initialization callback for all applicable beans...for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {smartSingleton.afterSingletonsInstantiated();return null;}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}smartInitialize.end();}}}

注意, 这里是预加载, 预加载会加载所有的非懒加载的的单例的非抽象的 bean .而懒加载, 其实也是在 getBean ()的时候才会加载的.

延申

你有没有了解 BeanPostProcessor?
BeanPostProcessor 本质上也是 bean

参考一下 refresh () 的 registerBeanPostProcessors(beanFactory);

	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);}
	public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {// WARNING: Although it may appear that the body of this method can be easily// refactored to avoid the use of multiple loops and multiple lists, the use// of multiple lists and multiple passes over the names of processors is// intentional. We must ensure that we honor the contracts for PriorityOrdered// and Ordered processors. Specifically, we must NOT cause processors to be// instantiated (via getBean() invocations) or registered in the ApplicationContext// in the wrong order.//// Before submitting a pull request (PR) to change this method, please review the// list of all declined PRs involving changes to PostProcessorRegistrationDelegate// to ensure that your proposal does not result in a breaking change:// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22//获取到容器中所有的 BeanPostProcessor; Bean的后置处理器String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);// Register BeanPostProcessorChecker that logs an info message when// a bean is created during BeanPostProcessor instantiation, i.e. when// a bean is not eligible for getting processed by all BeanPostProcessors.int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));// Separate between BeanPostProcessors that implement PriorityOrdered,// Ordered, and the rest.List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {  //获取所有实现了 PriorityOrdered 的 BeanPostProcessorBeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);priorityOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}//首先,注册所有的实现了 PriorityOrdered 的 BeanPostProcessor ;  First, register the BeanPostProcessors that implement PriorityOrdered.sortPostProcessors(priorityOrderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);//接下来,注册所有的实现了 Ordered 的 BeanPostProcessor  Next, register the BeanPostProcessors that implement Ordered.List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());for (String ppName : orderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); //获取后置处理器对象orderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}sortPostProcessors(orderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, orderedPostProcessors);// 最后,注册所有普通的 BeanPostProcessor ;Now, register all regular BeanPostProcessors.List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); //从容器中获取这个组件nonOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);//最后,重新注册所有internal的BeanPostProcessors  Finally, re-register all internal BeanPostProcessors.sortPostProcessors(internalPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, internalPostProcessors);// 重新注册一下这个后置处理器 Re-register post-processor for detecting inner beans as ApplicationListeners,// 把他放到后置处理器的最后一位; moving it to the end of the processor chain (for picking up proxies etc).beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}

相关文章:

从getBean()分析BeanFactory和ApplicationContext

本文说了哪些问题: BeanFactory 是啥ApplicationContext 是啥什么时候去实例化一个 bean, BeanFactory 和 ApplicationContext 实例化 bean 都是在什么时候 一个 Bean 什么时候被初始化 任何一个 Bean, 都是在 getBean () 的时候被初始化的.BeanFactory 需要字节手动调用 getb…...

详解Redis的主从同步原理

前言 Redis为了保证服务高可用&#xff0c;其中一种实现就是主从模式&#xff0c;即一个Redis服务端作为主节点&#xff0c;若干个Redis服务端作为主节点的从节点&#xff0c;从而实现即使某个服务端不可用时&#xff0c;也不会影响Redis服务的正常使用。本篇文章将对主从模式…...

前端项目上线后,浏览器缓存未刷新问题

文章目录问题背景一、解决办法二、实现原理关于缓存强缓存协商缓存刷新页面对浏览器的影响总结问题背景 前端页面开发测试完&#xff0c;要进行上线&#xff0c;某些页面上传更新到服务器之后&#xff0c;浏览器并没有更新&#xff0c;渲染的还是老页面。这是因为浏览器读了缓存…...

Vulnhub系列:Raven 1

该篇为Vulnhub系列靶机渗透&#xff0c;本次靶机存在4个flag。下面开始我们今天的渗透之旅。Raven靶机有很多种思路&#xff0c;我将对其进行一一整理。首先进行信息收集&#xff0c;利用arp-scan和nmap&#xff0c;进行靶机的ip及端口扫描发现了22、80、111端口。下面访问80端…...

MybatisPlus------多数据源环境(十一)

MybatisPlus------多数据源环境&#xff08;十一&#xff09; 生产环境中常常会存在多个数据源。 比如读写分离、一主多从、混合模式等等。 首先再pom文件中需要引入依赖&#xff1a; 多数据源所需要使用到的依赖 <!-- 多数据源所需要使用到的依赖--><depend…...

Tomcat+IDEA+Servlet能显示页面但提交form表单出现404问题

问题&#xff1a; 当我们使用tomcat启动&#xff0c;然后输入对应的url路径时候&#xff0c;能出现该html的页面&#xff0c;但提交表单后&#xff0c;却出现了404的问题&#xff0c;这时候我就很疑惑了....然后开始慢慢分析。 思路&#xff1a; 首先我们得知道404状态码是什…...

【蓝桥杯集训16】多源汇求最短路——Floyd算法(2 / 2)

目录 Floyd求最短路模板 4074. 铁路与公路 - floyd 脑筋急转弯 Floyd求最短路模板 活动 - AcWing 题目&#xff1a; 给定一个 n 个点 m 条边的有向图&#xff0c;图中可能存在重边和自环&#xff0c;边权可能为负数。 再给定 k 个询问&#xff0c;每个询问包含两个整数 x 和…...

simulink stateflow 状态机

系列文章目录 文章目录系列文章目录前言一、基操二、stateflow 数据三、chart动作四、chart的执行五、flow chart / junction六、状态机中的函数 Stateflow Functions七、chart层次结构八、案例——吸尘器机器人的驱动模式前言 一、基操 在tooltrip中选择DEBUG&#xff0c;通过…...

水库大坝安全监测的主要坝体类型介绍

水电站和水库大坝安全的分类中有重力坝、土石坝等不同的大坝形式。就在这里详细水库大坝安全监测按照建造形式&#xff0c;基本上可以分为三类&#xff1a;重力坝、土石坝和拱坝。 &#xff08;1&#xff09;重力坝 重力坝&#xff0c;顾名思义就是利用自身重力来维持坝体稳定…...

物理层概述(二)重点

目录前言编码与调制&#xff08;1&#xff09;基带信号与宽带信号编码与调制编码与调制&#xff08;2&#xff09;数字数据编码为数字信号非归零编码【NRZ】曼斯特编码差分曼彻斯特编码数字数据调制为模拟信号模拟数据如何编码为数字信号模拟数据调制为模拟信号物理层传输介质导…...

成都待慕电商:抖音极速版商品卡免佣扶持政策规则

新规&#xff0c;抖音极速版推出商品卡免佣扶持政策规则&#xff0c;本次抖音规则如何规定&#xff1f;具体往下看&#xff1a;一、政策简介1.1政策介绍为了更好地满足用户消费需求&#xff0c;丰富商家经营模式&#xff0c;降低商家经营成本&#xff0c;现平台针对商品卡场景推…...

青岛双软认定标准

软件企业的认定是有一定的标准的&#xff0c;需要满足以下这些条件&#xff1a;1、在我国境内依法设立了企业法人的企业&#xff1b;2、以计算机软件开发生产、系统集成、应用服务和其他相应技术服务为经营业务和主要经营收入&#xff1b;3、具有一种以上由本企业开发或由本企业…...

【00后卷王秘籍】python自动化测试—Python自动化框架及工具

1 、概述 手续的关于测试的方法论&#xff0c;都是建立在之前的文章里面提到的观点&#xff1a; 功能测试不建议做自动化 接口测试性价比最高 接口测试可以做自动化 后面所谈到的 测试自动化 也将围绕着 接口自动化 来介绍。 本系列选择的测试语言是 python 脚本语言。由于其…...

MySQL数据库基本操作

DDL 1、DDL解释 DDL(Data Definition Language)&#xff0c;数据定义语言&#xff0c;该语言部分包括以下内容&#xff1a; 对数据库的常用操作 对表结构的常用操作 修改表结构1、对数据库的常用操作 2、对表结构的常用操作-创建表 创建表格式 3、对表结构的常用操作-创建表…...

2023年最新的站内SEO指南:如何通过关键词优化提高网站排名

SEO或搜索引擎优化是指通过改善网站的内部和外部元素&#xff0c;以获得更好的自然搜索引擎排名和更多的网站流量。 链接建设和外链是SEO的重要组成部分&#xff0c;因为它们可以提高网站的权威性和可信度&#xff0c;从而使其在搜索引擎中排名更高。 在此指南中&#xff0c;…...

【Java】Java环开发环境安装

Java环开发环境安装 简介&#xff1a; 如果要从事Java编程&#xff0c;则需要安装JDK&#xff0c;如果仅仅是运行一款Java程序则JRE就满足要求。 Java的安装包分为两类 一类是JRE其就是一个独立的Java运行环境&#xff1b; 一类是JDK其是Java的开发环境&#xff0c;不过在JDK…...

[蓝桥杯] 枚举、模拟和排列问题

文章目录 一、连号区间数 1、1 题目描述 1、2 题解关键思路与解答 二、递增三元组 2、1 题目描述 2、2 题解关键思路与解答 三、错误票据 3、1 题目描述 3、2 题解关键思路与解答 四、回文日期 4、1 题目描述 4、2 题解关键思路与解答 五、归并排序 标题&#xff1a;蓝桥杯——…...

C++基础了解-02-C++ 数据类型

C 数据类型 一、C 数据类型 使用编程语言进行编程时&#xff0c;需要用到各种变量来存储各种信息。变量保留的是它所存储的值的内存位置。这意味着&#xff0c;当创建一个变量时&#xff0c;就会在内存中保留一些空间。 可能需要存储各种数据类型&#xff08;比如字符型、宽…...

关于MSVCR100.dll、MSVCR100d.dll、Msvcp100.dll、abort()R6010等故障模块排查及解决方法

一、常见故障介绍  最近在开发相机项目&#xff08;项目细节由于公司保密就不介绍了&#xff09;&#xff0c;程序运行5个来月以来首次出现msvcr100.dll故障等问题&#xff0c;于是乎开始了分析之路&#xff0c;按照度娘上的一顿操作&#xff0c;期间也是出现了各种不一样的问…...

【蓝桥杯集训·每日一题】AcWing 3305. 作物杂交

文章目录一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解三、知识风暴Spfa算法一、题目 1、原题链接 3305. 作物杂交 2、题目描述 作物杂交是作物栽培中重要的一步。 已知有 N 种作物 (编号 1 至 N)&#xff0c;第 i 种作物从播种到成熟的时间…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...