Spring源码分析のBean创建流程(上)

news2025/7/19 20:12:11

文章目录

  • 前言
  • 一、preInstantiateSingletons
    • 1.1、getMergedLocalBeanDefinition
    • 1.2、isFactoryBean
  • 二、getBean


前言

  原生Spring在refresh方法中,会在finishBeanFactoryInitializationpreInstantiateSingletons方法中直接创建所有非懒加载的单例Bean


一、preInstantiateSingletons

  preInstantiateSingletons方法的主要逻辑:

  1. 遍历bean名称的集合。
  2. 合并bean的定义 得到合并后的BeanDefinition。
  3. 判断bean是否应该在此处被实例化。
  4. 判断bean是否属于FactoryBean/SmartFactoryBean。
  5. 进行实例化。
  6. 实例化完成后,再次判断bean是否实现了SmartInitializingSingleton接口,如果实现了,则回调其中的afterSingletonsInstantiated方法。
	@Override
	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.
		//存放所有bean的名称
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		//遍历bean名称的集合
		for (String beanName : beanNames) {
			//1.1 getMergedLocalBeanDefinition 合并bean的定义 得到合并后的BeanDefinition
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//进入该分支的条件
			//1、Bean不是抽象的
			//2、bean是单例
			//3、bean不是懒加载
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//1.2 isFactoryBean 判断bean是否实现了FactoryBean接口
				if (isFactoryBean(beanName)) {
					//如果实现了 就获取实现了FactoryBean接口的bean 
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						//进行强转 将bean转换为接口FactoryBean的类型
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						//这一块是判断bean实现的是否是SmartFactoryBean  SmartFactoryBean 也是继承自 FactoryBean
						//只要满足条件,无论是if还是else都会回调SmartFactoryBean 的 isEagerInit 方法的逻辑 这里if分支只是额外加入了安全判断
						if (System.getSecuritbeanyManager() != 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 {
					getBean(beanName);
				}
			}
		}

		//在创建/获取bean之后 再次进行判断 如果有的bean实现了SmartInitializingSingleton 接口, 同样会去回调其中的afterSingletonsInstantiated方法。
		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();
			}
		}
	}

1.1、getMergedLocalBeanDefinition

  getMergedLocalBeanDefinition方法的作用是,得到合并后的bean定义。这里牵涉到Spring父子容器的概念:

public class Demo1 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext contextParent = new AnnotationConfigApplicationContext(AppConfigParent.class);
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(AppConfigParent.class);
        context.setParent(contextParent);
        context.refresh();
    }
}

  以上是在配置文件中关于父子容器的定义,假如在context中获取某个bean,而context中没有,就会去它的父容器中找。
  而在Spring中,合并父子bean定义,主要的逻辑:

  • 如果当前bean没有父类,则直接克隆当前的BeanDefinition,并使用它作为最终的合并结果。
  • 如果有父类,则递归调用getMergedLocalBeanDefinition去进行合并。
	protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
		// Quick check on the concurrent map first, with minimal locking.
		//去合并后的bean定义缓存中找
		RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
		//如果能找到就直接返回
		if (mbd != null && !mbd.stale) {
			return mbd;
		}
		//否则进行合并
		return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
	}

	/**
	*	参数一 当前的bean名称 参数二 根据当前bean名称找到的对应的bean定义
	*/
	protected RootBeanDefinition getMergedBeanDefinition(
			String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
			throws BeanDefinitionStoreException {

		//加锁 防止重复合并
		synchronized (this.mergedBeanDefinitions) {
			RootBeanDefinition mbd = null;
			RootBeanDefinition previous = null;

			// Check with full lock now in order to enforce the same merged instance.
			if (containingBd == null) {
				//再次尝试通过beanName 从 	mergedBeanDefinitions 中获取RootBeanDefinition 
				mbd = this.mergedBeanDefinitions.get(beanName);
			}

			//获取不到 就走合并的逻辑
			if (mbd == null || mbd.stale) {
				previous = mbd;
				//如果当前bean名称找到的对应的bean定义 的 父beanName属性为null
				//说明可能两种情况 :1、当前bean定义就是RootBeanDefinition 2、当前bean定义不需要合并
				if (bd.getParentName() == null) {
					// Use copy of given root bean definition.
					if (bd instanceof RootBeanDefinition) {
						mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
					}
					else {
						mbd = new RootBeanDefinition(bd);
					}
				}
				//否则需要合并
				else {
					// Child bean definition: needs to be merged with parent.
					BeanDefinition pbd;
					try {
						//对当前bean的父bean进行名称转换
						String parentBeanName = transformedBeanName(bd.getParentName());
						//当前bean名称和父bean名称不相同
						if (!beanName.equals(parentBeanName)) {
							//递归合并 因为当前bean 的 父bean有可能还有父bean
							pbd = getMergedBeanDefinition(parentBeanName);
						}
						//当前bean名称和父bean名称相同
						else {
							//获取父 BeanFactory
							BeanFactory parent = getParentBeanFactory();
							if (parent instanceof ConfigurableBeanFactory) {
								// 从父工厂中获取合并后的父类 BeanDefinition
								pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
							}
							else {
								throw new NoSuchBeanDefinitionException(parentBeanName,
										"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
												"': cannot be resolved without a ConfigurableBeanFactory parent");
							}
						}
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
								"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
					}
					// Deep copy with overridden values.
					//创建一个新的 RootBeanDefinition,基于父类 BeanDefinition
					mbd = new RootBeanDefinition(pbd);
					//当前的bd覆盖父类的属性
					mbd.overrideFrom(bd);
				}

				// Set default singleton scope, if not configured before.
				//如果没有设置作用域 默认是单例的
				if (!StringUtils.hasLength(mbd.getScope())) {
					mbd.setScope(SCOPE_SINGLETON);
				}

				// A bean contained in a non-singleton bean cannot be a singleton itself.
				// Let's correct this on the fly here, since this might be the result of
				// parent-child merging for the outer bean, in which case the original inner bean
				// definition will not have inherited the merged outer bean's singleton status.
				if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
					mbd.setScope(containingBd.getScope());
				}

				// Cache the merged bean definition for the time being
				// (it might still get re-merged later on in order to pick up metadata changes)
				//进行缓存
				if (containingBd == null && isCacheBeanMetadata()) {
					this.mergedBeanDefinitions.put(beanName, mbd);
				}
			}
			if (previous != null) {
				copyRelevantMergedBeanDefinitionCaches(previous, mbd);
			}
			//返回合并后的定义
			return mbd;
		}
	}

1.2、isFactoryBean

  isFactoryBean主要用于判断当前的bean是否实现了FactoryBean接口,如果某个类实现了FactoryBean接口,则会产生两个实例,第一个是实现了FactoryBean接口的bean的本身,第二个是其中getObject()方法返回的实例。默认的getBean(),得到的是getObject()方法返回的实例。如果要获取实现了FactoryBean接口的bean的本身,则需要getBean()时在名称前加上"&"符号。

	@Override
	public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
		//这里获取到的是实现了`FactoryBean`接口的bean的本身
		String beanName = transformedBeanName(name);
		//尝试从单例池中获取
		Object beanInstance = getSingleton(beanName, false);
		//如果获取到了,就判断是否实现了FactoryBean
		if (beanInstance != null) {
			return (beanInstance instanceof FactoryBean);
		}
		// 判断是否要从父容器中获取
		if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
			// No bean definition found in this factory -> delegate to parent.
			return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
		}
		//这里也会走bean定义合并
		return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
	}

	/**
	*	这里的isFactoryBean属性作为一个缓存的效果,后续直接取该类bean定义的该属性的值即可。
	*
	*/
	protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
		//尝试从合并后的bean定义中 获取isFactoryBean属性
		Boolean result = mbd.isFactoryBean;
		//获取不到
		if (result == null) {
			//判断当前bean是否实现了FactoryBean接口
			Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
			result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
			//并且将isFactoryBean属性设置值。
			mbd.isFactoryBean = result;
		}
		return result;
	}

二、getBean

  getBean是Spring创建所有非懒加载单例bean的方法,总体的逻辑,如果容器中已经有了目标bean,就直接返回,否则就去创建。
  该方法有以下的情况:

  1. 单例池中能获取到,走实例化 bean 的逻辑。
  2. 单例池中没有,Bean 父工厂不为空并且在 Bean 定义中不存在该 BeanName,委托给父工厂。父工厂会尝试获取该 Bean,如果父工厂也没有,则继续查找。
  3. 单例池中没有,Bean 父工厂为空并且在 Bean 定义中存在该 BeanName,则进行 Bean 定义合并。合并时,父 Bean 定义会被合并到当前 Bean 定义中,最终生成 Bean 实例。
  4. 根据 Bean 的作用域执行不同操作:
    • 单例 Bean:创建后加入单例缓存池,后续请求直接返回缓存中的实例。
    • 原型 Bean:每次请求创建新的实例,不缓存。
    • 其他作用域:根据配置的作用域(如 request、session 等)执行对应的实例化和管理逻辑。
  5. 循环依赖的处理:Spring 会通过提前暴露实例来解决 单例 Bean 的循环依赖问题,原型 Bean 则无法解决循环依赖。
  6. 初始化和销毁:Spring 会在容器启动时初始化单例 Bean,并处理 Bean 的初始化和销毁方法。
	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
		
		//对bean的名称进行转换 这里会去除beanName中的&
		String beanName = transformedBeanName(name);
		Object beanInstance;

		// Eagerly check singleton cache for manually registered singletons.
		//尝试从单例池中获取bean 
		Object sharedInstance = getSingleton(beanName);
		//单例池中能获取到
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			//实例化bean
			beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		//单例池中没有 说明是第一次获取
		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			//判断是否存在循环依赖的问题
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			//得到bean工厂
			BeanFactory parentBeanFactory = getParentBeanFactory();
			//bean工厂不为空 并且在bean定义中不存在该beanName
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				//如果传入的name中,有&字符串,则在此处重新加上&字符串
				String nameToLookup = originalBeanName(name);
				 // 如果父工厂是 AbstractBeanFactory 类型
				if (parentBeanFactory instanceof AbstractBeanFactory) {
				// 委托给父工厂执行 doGetBean 方法,查找并返回 Bean 实例
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				 // 如果传入了构造参数 args
				else if (args != null) {
					// 委托给父工厂并传递构造参数来获取 Bean 实例
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				// 如果指定了 requiredType 类型
				else if (requiredType != null) {
					// 委托给父工厂的标准 getBean 方法
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					// 委托给父工厂的标准 getBean 方法,返回该 Bean
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}

			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
					.tag("beanName", name);
			try {
				if (requiredType != null) {
					beanCreation.tag("beanType", requiredType::toString);
				}
				//进行bean定义合并
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				//如果bean定义是抽象的,则抛出异常
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				//找到该bean定义的DependsOn属性。
				//@DependsOn注解,用于标记在创建该bean时,应该先创建该bean依赖的某个bean
				String[] dependsOn = mbd.getDependsOn();
				//如果存在依赖的bean
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						//这里是对于循环依赖的判断 即当前bean所依赖的bean,又依赖了当前bean
						//这种情况等价于 构造方法的循环依赖 无解 所以直接抛出异常
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						//注册bean的依赖关系
						registerDependentBean(dep, beanName);
						try {
							//先去创建当前bean所依赖的bean
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}


				// 下面这一段的逻辑 根据bean不同的作用域 执行不同的操作 单例bean就直接创建 并加入单例池
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
					beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				//原型bean会创建 不会被缓存
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}
				//其他的作用域,走自己的初始化逻辑
				else {
					String scopeName = mbd.getScope();
					if (!StringUtils.hasLength(scopeName)) {
						throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
					}
					Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new ScopeNotActiveException(beanName, scopeName, ex);
					}
				}
			}
			catch (BeansException ex) {
				beanCreation.tag("exception", ex.getClass().toString());
				beanCreation.tag("message", String.valueOf(ex.getMessage()));
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
			finally {
				beanCreation.end();
			}
		}

		return adaptBeanInstance(name, beanInstance, requiredType);
	}

  其中bean的依赖关系,是存放在DefaultSingletonBeanRegistry的成员变量中:
在这里插入图片描述dependentBeanMap: 当前bean被哪些bean依赖;dependenciesForBeanMap:当前bean依赖了哪些bean
  然后会调用createBean方法完成bean的创建。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2300049.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DeepSeek笔记(二):DeepSeek局域网访问

如果有多台电脑&#xff0c;可以通过远程访问&#xff0c;实现在局域网环境下多台电脑共享使用DeepSeek模型。在本笔记中&#xff0c;首先介绍设置局域网多台电脑访问DeepSeek-R1模型。 一、启动Ollama局域网访问 1.配置环境变量 此处本人的操作系统是Windows11&#xff0c;…

基于大数据的全国热门旅游景点数据分析系统的设计与实现

【大数据】基于大数据的全国热门旅游景点数据分析系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统主要包括登录注册、系统首页、图表分析、数据管理和个人信息五大功能模…

【Unity3D】Jenkins Pipeline流水线自动构建Apk

目录 一、准备阶段 二、创建Pipeline流水线项目 三、注意事项 四、扩展 1、Pipeline添加SVN更新项目Stage阶段 一、准备阶段 1、安装tomcat 10.0.5 Index of apache-local/tomcat/tomcat-10 2、安装jdk 17 Java Archive Downloads - Java SE 17.0.13 and later 3、…

Edge浏览器翻译|自动翻译设置

文章目录 Edge浏览器翻译|自动翻译设置右键翻译显示原文 Edge浏览器翻译|自动翻译设置 在 Microsoft Edge 浏览器中使用 Microsoft Translator - Microsoft 支持 进入浏览器设置,从首选语言列表中移除多余的语言设置 网站将以受支持语言列表中的第一种语言进行显示。若要重新…

基于微信小程序的场地预约设计与实现

第3章 系统设计 3.1系统设计目标 本系统的实现可以帮助体育馆场地信息的管理。帮助管理员对注册用户管理以及用户预约管理。同时可以帮助用户进行场地预约。本系统可以实现用户足不出户预约到需要的场地&#xff0c;为用户提供场地信息了解的平台。 3.2系统功能结构图 本系统的…

腾讯发布混元-3D 2.0: 首个开源高质3D-DiT生成大模型

在之前的文章中已经和大家介绍过腾讯HunYuan-3D 1.0&#xff0c;感兴趣的小伙伴可以点击下面链接阅读~ HunYuan-3D 是首个开源高质3D-DiT生成大模型&#xff0c;几何与纹理解藕生成&#xff0c;一键将创意具象化。 2.0模型架构图及介绍 2.0模型将几何和纹理生成解耦&#xff0…

计算机性能与网络体系结构探讨 —— 基于《计算机网络》谢希仁第八版

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…

基于vue3实现的课堂点名程序

设计思路 采用vue3实现的课堂点名程序&#xff0c;模拟课堂座位布局&#xff0c;点击开始点名按钮后&#xff0c;一朵鲜花在座位间传递&#xff0c;直到点击结束点名按钮&#xff0c;鲜花停留的座位被点名。 课堂点名 座位组件 seat.vue <script setup>//组合式APIimpo…

kkFileView二开之pdf转图片接口

kkFileView二开之Pdf转图片接口 kkFileView二开系列文章&#xff1a;1 kkFileView源码下载及编译2 Pdf转图片接口2.1 背景2.2 分析2.2 接口开发2.2.1 编写Pdf转图片方法2.2.2 编写转换接口 2.3 接口测试2.3.1 Pdf文件准备2.3.2 pdf2Image 3 部署 kkFileView二开系列文章&#x…

神经网络常见激活函数 9-CELU函数

文章目录 CELU函数导函数函数和导函数图像优缺点pytorch中的CELU函数tensorflow 中的CELU函数 CELU 连续可微指数线性单元&#xff1a;CELU&#xff08;Continuously Differentiable Exponential Linear Unit&#xff09;,是一种连续可导的激活函数&#xff0c;结合了 ELU 和 …

什么是网关?网关有什么作用?API网关的主要功能,SpringCloud可以选择有哪些API网关?什么是限流算法?网关如何实现限流?一篇文章读懂网关的前世今生

1、什么是网关&#xff1f; API网关&#xff08;API Gateway&#xff09;是一种中间层服务器&#xff0c;用于集中管理&#xff0c;保护和路由对后端服务的访问。它充当了客户端与后端服务之间的入口点&#xff0c;提供了一组统一的接口管理和控制API的访问。 2、网关示意图 3…

从安装软件到flask框架搭建可视化大屏(一)——创建一个flask页面,零基础也可以学会

1.第一步&#xff1a;安装软件 Flask是一个轻量级Web应用框架&#xff0c;用python代码编写&#xff0c;简单方便应用。 如何安装pycharm_pycharm只能安装在c盘吗-CSDN博客 Pycharm分为专业版和社区版&#xff0c;是python的主流工具 如何安装Anaconda_如何安装anacoda csdn-…

python opencv基础使用总结

1.安装opencv库&#xff1a;pip install opencv-python 2.基础使用范例 import cv2 #图片的基本操作#1.读取一张图片 参数 1&#xff1a;图片的文件名如果图片放在当前文件夹下&#xff0c;直接写文件名就行&#xff0c;如lena.jpg否则需要给出绝对路径&#xff0c;如D:\Ope…

【已解决】TypeError: AsyncConnectionPool.__init__(), new install bug, httpx==0.24.1

1&#xff0c;参考社区链接&#xff0c;首先降低gradio版本&#xff0c;降低到4以下&#xff0c;但是也不能降太低&#xff0c;也不能太高&#xff0c;要适中&#xff0c;推荐版本3.39.0 pip install gradio3.39.0 2&#xff0c;下载正确的httpx版本 参考社区链接&#xff0…

清华大学KVCache.AI团队联合趋境科技联合的KTransformers开源项目为什么那么厉害

KTransformers是一个由清华大学KVAV.AI团队开发的开源项目&#xff0c;旨在优化大语言模型&#xff08;LLM&#xff09;的推理性能&#xff0c;特别是在有限显存资源下运行大型模型。以下是KTransformers的详细介绍&#xff1a; 1. 核心特点 高性能优化&#xff1a;KTransfor…

matlab模拟风场的随机脉动风

1、内容简介 matlab137-模拟风场的随机脉动风 可以交流、咨询、答疑 2、内容说明 略 模拟风场的随机脉动风&#xff0c;并进行相关的统计分析和计算&#xff0c;包括风速谱、空间相关性、自谱、互谱、以及POD&#xff08;Proper Orthogonal Decomposition&#xff09;分解等…

Code::Blocks 创建 C 项目 二

Code::Blocks 创建 C 项目 二 Code::Blocks 安装请看 Code::Blocks 安装 启动 Code Blocks 选择 Create a new project 弹出界面选择 Projects -> Console application -> Go 选择 C &#xff1a;表示创建的是 C 语言项目 点击 Next Project title&#xff1a;项目名 …

Javascript网页设计案例:通过PDF.js实现一款PDF阅读器,包括预览、页面旋转、页面切换、放大缩小、黑夜模式等功能

前言 目前功能包括&#xff1a; 切换到首页。切换到尾页。上一页。下一页。添加标签。标签管理页面旋转页面随意拖动双击后还原位置 其实按照自己的预期来说&#xff0c;有很多功能还没有开发完&#xff0c;配色也没有全都搞完&#xff0c;先发出来吧&#xff0c;后期有需要…

【IoTDB 线上小课 11】为什么 DeepSeek 要选择开源?

新年新气象&#xff0c;【IoTDB 视频小课】第十一期全新来临&#xff01; 关于 IoTDB&#xff0c;关于物联网&#xff0c;关于时序数据库&#xff0c;关于开源... 一个问题重点&#xff0c;3-5 分钟&#xff0c;我们讲给你听&#xff1a; 开源“加成”再次展现&#xff01; 现在…

【ESP32】ESP-IDF开发 | WiFi开发 | HTTPS服务器 + 搭建例程

1. 简介 1.1 HTTPS HTTPS&#xff08;HyperText Transfer Protocol over Secure Socket Layer&#xff09;&#xff0c;全称安全套接字层超文本传输协议&#xff0c;一般理解为HTTPSSL/TLS&#xff0c;通过SSL证书来验证服务器的身份&#xff0c;并为浏览器和服务器之间的通信…