`
y806839048
  • 浏览: 1126322 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

理解Spring循环引用(循环依赖)

阅读更多

一、介绍

循环引用,也可以叫做循环依赖,就是A类依赖了B类,B类又依赖A类,比如下面这种情况:

 

class A {

private B b;

 

public B getB() {

return b;

}

 

public void setB(B b) {

this.b = b;

}

}

 

class B {

private A a;

 

public B(A a) {

this.a = a;

}

 

public A getA() {

return a;

}

}

 

 

在Spring容器中,可以通过依赖注入的方式,将A注入给B,同时也将B注入给A,那么这时在该容器中,A和B就存在循环依赖。当存在循环依赖的时候,某些情况下Spring可以正确处理,某些情况下,Spring会抛出异常。下面就讲解一下什么情况可以正确处理,什么情况会抛出异常。

 

在开始介绍各种情况之前,首先要了解以下三个知识点:

 

Spring中依赖注入的方式有两种,属性注入与构造器注入。上面的代码中,类A就是通过属性注入的方式注入了B,类B是通过构造器注入的方式注入了A。

 

Spring中的bean根据作用域的不同,可以大体分为两类,singleton和prototype。singleton在一个容器中,只会有一个实例;而prototype在每次调用时,都会产生一个新的实例。

 

Spring中,单例bean有延迟加载和立即加载两种加载方式,其中立即加载模式会在容器启动的时候就创建bean,而延迟加载会在容器启动后,使用到bean的时候再加载它。本篇分析一律使用延迟加载,因为有时候单例bean的加载顺序,会影响到创建bean的成功或失败。

 

单利对象创建之初会保持引用,后面set的时候只要发现这个要set的有引用,不再创建只返回引用----打破循环创建,多例对象不会保存引用(保存引用就成了单利)--不保存引用后面set找不到之前创建的bean

 

引用者A自己创建,被注入bean这也会发起被注入的创建

A通过引用注入的bean,这个A可以先通过无参构造函数创建(保证自己被创建出来),然后由于引用创建bean的时候,无需等待这个bean的依赖创建好,直接用之前bean自己创建时保存的引用,最后依赖的可以最后通过引用信息找到然后set注入(懒加载用的时候注入),使用构造函数注入的bean,这个被注入的bean需要完全被创建好才可自己被创建好,这样就失败

 

默认函数创建对象的时候可以先不管对象中的引用属性是否准备好,用有参数构造方法创建的时候就需要,里面构造参数的注入的属性全部准备好才可完成本实例的创建

 

这里考虑延时加载情况

 

对于上述三点不了解的朋友,可以看一下Spring依赖、Spring作用域和Spring延迟加载。

 

二、循环依赖的bean都是通过构造器注入的情况

2.1 循环依赖的bean都是singleton

示例代码:

 

class A {

private B b;

 

public B getB() {

return b;

}

 

public A(B b) {

this.b = b;

}

}

 

class B {

private A a;

 

public A getA() {

return a;

}

 

public B(A a) {

this.a = a;

}

}

 

配置文件:

 

<bean id="singletonA" class="ccc.spring.circulardependencies.constructor.A" lazy-init="true">

<constructor-arg name="b" ref="singletonB"/>

</bean>

<bean id="singletonB" class="ccc.spring.circulardependencies.constructor.B" lazy-init="true">

<constructor-arg name="a" ref="singletonA"/>

</bean>

 

 

测试代码:

 

ApplicationContext applicationContext =

new ClassPathXmlApplicationContext("ApplicationContext.xml");

A a = (A) applicationContext.getBean("singletonA");

 

测试结果:

 

失败

 

org.springframework.beans.factory.BeanCreationException: 

Error creating bean with name 'singletonA' defined in class path resource [ApplicationContext.xml]: Cannot resolve reference to bean 'singletonB' while setting constructor argument; 

nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'singletonB' defined in class path resource [ApplicationContext.xml]: Cannot resolve reference to bean 'singletonA' while setting constructor argument; 

nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'singletonA': Requested bean is currently in creation: Is there an unresolvable circular reference?

 

 

上面的代码中,singletonA和singletonB都是单例,并且通过构造器注入的方式依赖于对方,这种情况下获取任何一个bean的时候都会失败,Spring抛出BeanCreationException异常。

 

2.2 循环依赖的bean都是prototype

示例代码

 

和2.1节相同。

 

配置文件

 

<bean id="prototypeA" class="ccc.spring.circulardependencies.constructor.A" scope="prototype">

<constructor-arg name="b" ref="prototypeB"/>

</bean>

<bean id="prototypeB" class="ccc.spring.circulardependencies.constructor.B" scope="prototype">

<constructor-arg name="a" ref="prototypeA"/>

</bean>

 

 

测试代码

 

ApplicationContext applicationContext =

new ClassPathXmlApplicationContext("ApplicationContext.xml");

 

A a = (A) applicationContext.getBean("singletonA");

 

 

测试结果

 

失败

 

org.springframework.beans.factory.BeanCreationException: 

Error creating bean with name 'prototypeA' defined in class path resource [ApplicationContext.xml]: Cannot resolve reference to bean 'prototypeB' while setting constructor argument; 

nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'prototypeB' defined in class path resource [ApplicationContext.xml]: Cannot resolve reference to bean 'prototypeA' while setting constructor argument; 

nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'prototypeA': Requested bean is currently in creation: Is there an unresolvable circular reference?

 

 

该例中A和B都是prototype,并且通过构造器注入了对方。在获取bean的时候,同样抛出了BeanCreationException异常。

 

2.3 循环依赖的bean同时有singleton和prototype

实例代码

 

和2.1节相同。

 

配置文件

 

<bean id="mixSingletonA" class="ccc.spring.circulardependencies.constructor.A" lazy-init="true">

<constructor-arg name="b" ref="mixPrototypeB"/>

</bean>

<bean id="mixPrototypeB" class="ccc.spring.circulardependencies.constructor.B"  scope="prototype">

<constructor-arg name="a" ref="mixSingletonA"/>

</bean>

 

 

测试代码

 

先获取singleton的情况:

 

ApplicationContext applicationContext =

new ClassPathXmlApplicationContext("ApplicationContext.xml");

 

A a = (A) applicationContext.getBean("mixSingletonA");

 

 

先获取protytype的情况:

 

ApplicationContext applicationContext =

new ClassPathXmlApplicationContext("ApplicationContext.xml");

 

B b = (B) applicationContext.getBean("mixPrototypeB");

 

 

测试结果

 

先获取singleton的情况:

 

失败

 

org.springframework.beans.factory.BeanCreationException: 

Error creating bean with name 'mixSingletonA' defined in class path resource [ApplicationContext.xml]: Cannot resolve reference to bean 'mixPrototypeB' while setting constructor argument; 

nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mixPrototypeB' defined in class path resource [ApplicationContext.xml]: Cannot resolve reference to bean 'mixSingletonA' while setting constructor argument; 

nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'mixSingletonA': Requested bean is currently in creation: Is there an unresolvable circular reference?

 

 

 

先获取protytype的情况:

 

失败

 

org.springframework.beans.factory.BeanCreationException: 

Error creating bean with name 'mixPrototypeB' defined in class path resource [ApplicationContext.xml]: Cannot resolve reference to bean 'mixSingletonA' while setting constructor argument; 

nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mixSingletonA' defined in class path resource [ApplicationContext.xml]: Cannot resolve reference to bean 'mixPrototypeB' while setting constructor argument; 

nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'mixPrototypeB': Requested bean is currently in creation: Is there an unresolvable circular reference?

 

 

该例中,mixSingletonA是singleton,mixPrototypeB是prototype,在Spring容器启动后,无论是先获得谁,获取bean都会失败,并抛出BeanCreationException。

 

2.4 小结

当循环依赖的bean都是通过构造器注入依赖的时候,无论这些bean是singleton还是prototype,在获取bean的时候都会失败。

 

三、循环依赖的bean都是通过属性注入的情况

3.1 循环依赖的bean都是singleton

示例代码

 

class A {

private B b;

 

public B getB() {

return b;

}

 

public void setB(B b) {

this.b = b;

}

}

 

class B {

private A a;

 

public A getA() {

return a;

}

 

public void setA(A a) {

this.a = a;

}

}

 

 

 

配置文件

 

<bean id="singletonA" class="ccc.spring.circulardependencies.field.A" lazy-init="true">

<property name="b" ref="singletonB"/>

</bean>

<bean id="singletonB" class="ccc.spring.circulardependencies.field.B" lazy-init="true">

<property name="a" ref="singletonA"/>

</bean>

 

 

测试代码

 

ApplicationContext applicationContext =

new ClassPathXmlApplicationContext("ApplicationContext.xml");

A a = (A) applicationContext.getBean("singletonA");

B b = (B) applicationContext.getBean("singletonB");

assertEquals(a, b.getA());

assertEquals(b, a.getB());

 

 

测试结果

 

运行成功。

 

该例中singletonA和singletonB都是singleton,并且通过属性注入的方式依赖对方,在Spring容器启动后,无论是先获得哪个bean,都会成功。

 

3.2 循环依赖的bean都是prototype

示例代码

 

和3.1节相同。

 

配置文件

 

<bean id="prototypeA" class="ccc.spring.circulardependencies.field.A" scope="prototype">

<property name="b" ref="prototypeB"/>

</bean>

<bean id="prototypeB" class="ccc.spring.circulardependencies.field.B" scope="prototype">

<property name="a" ref="prototypeA"/>

</bean>

 

 

测试代码

 

ApplicationContext applicationContext =

new ClassPathXmlApplicationContext("ApplicationContext.xml");

 

A a = (A) applicationContext.getBean("prototypeA");

 

 

测试结果

 

失败

 

org.springframework.beans.factory.BeanCreationException: 

Error creating bean with name 'prototypeA' defined in class path resource [ApplicationContext.xml]: Cannot resolve reference to bean 'prototypeB' while setting bean property 'b'; 

nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'prototypeB' defined in class path resource [ApplicationContext.xml]: Cannot resolve reference to bean 'prototypeA' while setting bean property 'a'; 

nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'prototypeA': Requested bean is currently in creation: Is there an unresolvable circular reference?

 

 

该例中,prototypeA和prototypeB都是protytype,并且通过属性注入的方式依赖对方,在Spring容器启动后,无论是先获得哪个bean,都会失败,并抛出BeanCreationException异常。

 

3.3 循环依赖的bean同时有singleton和prototype

示例代码

 

和3.1节相同。

 

配置文件

 

<bean id="mixSingletonA" class="ccc.spring.circulardependencies.field.A" lazy-init="true">

<property name="b" ref="mixPrototypeB"/>

</bean>

<bean id="mixPrototypeB" class="ccc.spring.circulardependencies.field.B" scope="prototype">

<property name="a" ref="mixSingletonA"/>

</bean>

 

 

测试代码

 

先获取singleton的情况:

 

ApplicationContext applicationContext =

new ClassPathXmlApplicationContext("ApplicationContext.xml");

 

A a = (A) applicationContext.getBean("mixSingletonA");

B b = (B) applicationContext.getBean("mixPrototypeB");

assertNotEquals(a.getB(), b);

assertEquals(b.getA(), a);

 

 

 

先获取protytype的情况:

 

ApplicationContext applicationContext =

new ClassPathXmlApplicationContext("ApplicationContext.xml");

 

expectedEx.expect(BeanCreationException.class);

B b = (B) applicationContext.getBean("mixPrototypeB");

 

 

测试结果

 

先获取singleton的情况:成功

 

先获取singleton的情况:失败

 

org.springframework.beans.factory.BeanCreationException: 

Error creating bean with name 'mixPrototypeB' defined in class path resource [ApplicationContext.xml]: Cannot resolve reference to bean 'mixSingletonA' while setting bean property 'a'; 

nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mixSingletonA' defined in class path resource [ApplicationContext.xml]: Cannot resolve reference to bean 'mixPrototypeB' while setting bean property 'b'; 

nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'mixPrototypeB': Requested bean is currently in creation: Is there an unresolvable circular reference?

 

该例中,mixSingletonA是singleton,mixPrototypeB是prototype,并且都通过属性注入的方式依赖的对方。

 

当容器启动后,如果先获取的是singleton,那么两个bean都能成功获得。但是如果先获取的是prototype,那么就会失败。注意本例中的mixSingletonA是延迟加载的,所以只有在真正获取该bean的时候Spring容器才会去创建bean。

 

3.4 小结

当循环依赖的bean都是通过属性注入依赖的时候,根据bean的作用域是singleton还是prototpye,会有不同的表现。

 

如果循环依赖的bean都是singleton,那么无论先获取哪个bean,都能成功。

如果循环依赖的bean都是prototype,那么无论先获取哪个bean,都会失败。

如果循环依赖的bean中有singleton,也有prototype,那么当先获取的那个bean是singleton时,就会成功,否则失败。

四、循环依赖的bean同时有属性注入和构造器注入的情况

当循环依赖的bean同时有属性注入和构造器注入的时候,情况有点多,就不一一详细,这里只介绍可以运行成功的情况。

 

4.1 循环依赖的bean都是singleton,且在容器启动后先去获取通过属性注入依赖的bean

实例代码

 

class A {

private B b;

 

public B getB() {

return b;

}

 

public A(B b) {

this.b = b;

}

}

 

 

class B {

private A a;

 

public A getA() {

return a;

}

 

public void setA(A a) {

this.a = a;

}

}

 

 

配置文件

 

<bean id="singletonA" class="ccc.spring.circulardependencies.mix.A" lazy-init="true">

<constructor-arg name="b" ref="singletonB"/>

</bean>

<bean id="singletonB" class="ccc.spring.circulardependencies.mix.B" lazy-init="true">

<property name="a" ref="singletonA"/>

</bean>

 

 

测试代码

 

ApplicationContext applicationContext =

new ClassPathXmlApplicationContext("ApplicationContext.xml");

B b = (B) applicationContext.getBean("singletonB");

A a = (A) applicationContext.getBean("singletonA");

assertEquals(a, b.getA());

assertEquals(b, a.getB());

 

测试结果

 

成功

 

该例中singletonA和singletonB都是单例,但是singletonA是通过构造器注入的singletonB,而singletonB是通过属性注入的singletonA。当Spring容器启动后,如果先获取singletonB就会成功。

 

4.2 循环依赖的bean有singleton和prototype,其中singleton是通过属性注入依赖,prototype是通过构造器注入依赖。在容器启动后先获取singleton。

实例代码

 

和4.1节相同。

 

配置文件

 

<bean id="mixPrototypeA" class="ccc.spring.circulardependencies.mix.A" scope="prototype">

<constructor-arg name="b" ref="mixSingletonB"/>

</bean>

<bean id="mixSingletonB" class="ccc.spring.circulardependencies.mix.B" lazy-init="true">

<property name="a" ref="mixPrototypeA"/>

</bean>

 

测试代码

 

ApplicationContext applicationContext =

new ClassPathXmlApplicationContext("ApplicationContext.xml");

 

B b = (B) applicationContext.getBean("mixSingletonB");

A a = (A) applicationContext.getBean("mixPrototypeA");

assertNotEquals(a, b.getA());

 

 

测试结果

 

成功

 

该例中mixPrototypeA是prototype,mixSingletonB都是singleton,但是mixPrototypeA是通过构造器注入的mixSingletonB,而mixSingletonB是通过属性注入的mixPrototypeA。当Spring容器启动后,如果先获取mixSingletonB就会成功。

 

五、结论

通过上面三节的例子来看,可以得出以下结论:

 

如果循环依赖的bean都是通过构造器注入依赖,那么不管它们是singleton还是prototype,都会失败。

如果循环依赖的bean都是prototype,那么不管它们是通过构造器注入依赖还是通过属性注入依赖,都会失败。

如果循环依赖的bean既有构造器注入也有属性注入,既有singleton也有prototype,在容器启动后,只有当获取的第一个bean是通过属性注入依赖的singleton时,才会成功,别的情况都会失败。

所以最终结论就是:

 

如果多个bean存在循环依赖,在Spring容器启动后,只有当获取的第一个bean是通过属性注入依赖的singleton时,才会成功,别的情况都会失败

 

六、分析

循环引用的bean之间必然会构成一个环,如下图所示,A、B、C之间构成了一个环形。

 

 

 

当Spring容器在创建A时,会发现其引用了B,从而会先去创建B。同样的,创建B时,会先去创建C,而创建C时,又先去创建A。最后A、B、C之间互相等待,谁都没法创建成功。

 

要想打破这个环,那么这个环中至少需要有一个bean可以在自身的依赖还没有得到满足前,就能够被创建出来(最起码要被实例化出来,可以先不注入其需要的依赖)。这种bean只能是通过属性注入依赖的类,因为它们可以先使用默认构造器创建出实例,然后再通过setter方法注入依赖。而通过构造器注入依赖的类,在它的依赖没有被满足前,无法被实例化。而且这个bean,还必须是singleton,不能是prototype。至于为什么不能是prototype呢,我们一起来回顾一下3.1节的例子:

 

3.1节中类A和类B都是通过属性注入依赖,并且他们都是singleton,配置文件如下:

 

<bean id="singletonA" class="ccc.spring.circulardependencies.field.A" lazy-init="true">

<property name="b" ref="singletonB"/>

</bean>

<bean id="singletonB" class="ccc.spring.circulardependencies.field.B" lazy-init="true">

<property name="a" ref="singletonA"/>

</bean>

 

Spring容器启动后,如果我们去获取singletonA,那么容器的操作步骤大致如下:

 

尝试创建bean singletonA,发现singletonA是singleton,且不是通过构造器注入依赖,那么先使用默认构造器创建一个A的实例,并保存对它的引用,并且将singletonA标记为“正在创建中的singleton”。然后发现singletonA依赖了singletonB,所以尝试创建singletonB。

尝试创建bean singletonB,发现singletonB是singleton,且不是通过构造器注入依赖,那么先使用默认构造器创建一个B的实例,并保存对它的引用,并且将singletonB标记为“正在创建中的singleton”。然后发现singletonB依赖了singletonA,所以尝试创建singletonA。

尝试创建singletonA,注意,这时Spring容器发现singletonA“正在创建中”,那么就不会再去创建singletonA,而是返回容器之前保存了的对singletonA的引用。

容器将singletonA通过setter方法注入到singletonB,从而singletonB完成创建。

容器将singletonB通过setter方法注入到singletonA,从而singletonA完成创建。

上述步骤,最重要的是第1步和第3步。在第1步中,容器会保存对singletonA的引用,在第3步中,再返回对singletonA的引用,从而可以成功创建那些依赖了singletonA的bean(本例中是singletonB)。这样,循环依赖的环就在singletonA这个点这里被打破。

 

那为什么prototype不能成为打破这个环的一个点呢?原因就在于Spring容器只会对singleton保存引用,而对于prototype,并不会对其保存引用,这就导致在第3步中并不能获得之前创建的bean(因为引用不到它)。

 

至于为什么容器不对prototype保存引用,那就涉及到singleton和portotpye的概念,如果也对prototype保存引用,那么其实它就变成了singleton。可以看一下Spring作用域。

 

按道理,在循环依赖的环里,只要有一个bean,是通过属性注入依赖,并且是singleton,那么这个环就可以被打破,无论获取他们的顺序是怎样。但是我们在第五节得出过结论“只有当获取的第一个bean是通过属性注入依赖的singleton时,才会成功”,为什么会这样呢?这就和Spring的实现有关了,当Spring容器遍历那些循环依赖的bean时,只要遍历到那种已经遍历过一次的bean,并且它们不是通过属性注入依赖的singleton时,就会直接抛出BeanCurrentlyInCreationException异常。

--------------------- 

 

原文:https://blog.csdn.net/chen2526264/article/details/80673598 

 

分享到:
评论

相关推荐

    ysoserial-master.zip

    ysoserial是一个用于生成利用不安全的Java对象反序列化的有效负载的概念验证工具。它包含一系列在常见Java库中发现的"gadget chains",可以在特定条件下利用执行不安全的反序列化操作的Java应用程序。ysoserial项目最初在2015年AppSecCali会议上提出,包含针对Apache Commons Collections(3.x和4.x版本)、Spring Beans/Core(4.x版本)和Groovy(2.3.x版本)的利用链

    zigbee CC2530无线自组网协议栈系统代码实现协调器与终端的TI Sensor实验和Monitor使用.zip

    1、嵌入式物联网单片机项目开发例程,简单、方便、好用,节省开发时间。 2、代码使用IAR软件开发,当前在CC2530上运行,如果是其他型号芯片,请自行移植。 3、软件下载时,请注意接上硬件,并确认烧录器连接正常。 4、有偿指导v:wulianjishu666; 5、如果接入其他传感器,请查看账号发布的其他资料。 6、单片机与模块的接线,在代码当中均有定义,请自行对照。 7、若硬件有差异,请根据自身情况调整代码,程序仅供参考学习。 8、代码有注释说明,请耐心阅读。 9、例程具有一定专业性,非专业人士请谨慎操作。

    YOLO算法-自卸卡车-挖掘机-轮式装载机数据集-2644张图像带标签-自卸卡车-挖掘机-轮式装载机.zip

    YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;

    Oracle10gDBA学习手册中文PDF清晰版最新版本

    **Oracle 10g DBA学习手册:安装Oracle和构建数据库** **目的:** 本章节旨在指导您完成Oracle数据库软件的安装和数据库的创建。您将通过Oracle Universal Installer (OUI)了解软件安装过程,并学习如何利用Database Configuration Assistant (DBCA)创建附加数据库。 **主题概览:** 1. 利用Oracle Universal Installer (OUI)安装软件 2. 利用Database Configuration Assistant (DBCA)创建数据库 **第2章:Oracle软件的安装与数据库构建** **Oracle Universal Installer (OUI)的运用:** Oracle Universal Installer (OUI)是一个图形用户界面(GUI)工具,它允许您查看、安装和卸载机器上的Oracle软件。通过OUI,您可以轻松地管理Oracle软件的安装和维护。 **安装步骤:** 以下是使用OUI安装Oracle软件并创建数据库的具体步骤:

    消防验收过程服务--现场记录表.doc

    消防验收过程服务--现场记录表.doc

    (4655036)数据库 管理与应用 期末考试题 数据库试题

    数据库管理\09-10年第1学期数据库期末考试试卷A(改卷参考).doc。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。

    YOLO算法-瓶纸盒合并数据集-3161张图像带标签-纸张-纸箱-瓶子.zip

    YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;

    职业暴露后的处理流程.docx

    职业暴露后的处理流程.docx

    Java Web开发短消息系统

    Java Web开发短消息系统

    java毕设项目之ssm基于java和mysql的多角色学生管理系统+jsp(完整前后端+说明文档+mysql+lw).zip

    项目包含完整前后端源码和数据库文件 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 服务器:tomcat7

    批量导出多项目核心目录工具

    这是一款可以配置过滤目录及过滤的文件后缀的工具,并且支持多个项目同时输出导出,并过滤指定不需要导出的目录及文件后缀。 导出后将会保留原有的路径,并在新的文件夹中体现。

    【图像压缩】基于matlab GUI DCT图像压缩(含MAX MED MIN NONE)【含Matlab源码 9946期】.zip

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    YOLO算法-挖掘机与火焰数据集-7735张图像带标签-挖掘机.zip

    YOLO算法-挖掘机与火焰数据集-7735张图像带标签-挖掘机.zip

    操作系统实验 Ucore lab5

    操作系统实验 Ucore lab5

    IMG_5950.jpg

    IMG_5950.jpg

    竞选报价评分表.docx

    竞选报价评分表.docx

    java系统,mysql、springboot等框架

    java系统,mysql、springboot等框架

    zigbee CC2530网关+4节点无线通讯实现温湿度、光敏、LED、继电器等传感节点数据的采集上传,网关通过ESP8266上传远程服务器及下发控制.zip

    1、嵌入式物联网单片机项目开发例程,简单、方便、好用,节省开发时间。 2、代码使用IAR软件开发,当前在CC2530上运行,如果是其他型号芯片,请自行移植。 3、软件下载时,请注意接上硬件,并确认烧录器连接正常。 4、有偿指导v:wulianjishu666; 5、如果接入其他传感器,请查看账号发布的其他资料。 6、单片机与模块的接线,在代码当中均有定义,请自行对照。 7、若硬件有差异,请根据自身情况调整代码,程序仅供参考学习。 8、代码有注释说明,请耐心阅读。 9、例程具有一定专业性,非专业人士请谨慎操作。

    YOLO算法-快递衣物数据集-496张图像带标签.zip

    YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;

    搜索引擎lucen的相关介绍 从事搜索行业程序研发、人工智能、存储等技术人员和企业

    内容概要:本文详细讲解了搜索引擎的基础原理,特别是索引机制、优化 like 前缀模糊查询的方法、建立索引的标准以及针对中文的分词处理。文章进一步深入探讨了Lucene,包括它的使用场景、特性、框架结构、Maven引入方法,尤其是Analyzer及其TokenStream的实现细节,以及自定义Analyzer的具体步骤和示例代码。 适合人群:数据库管理员、后端开发者以及希望深入了解搜索引擎底层实现的技术人员。 使用场景及目标:适用于那些需要优化数据库查询性能、实施或改进搜索引擎技术的场景。主要目标在于提高数据库的访问效率,实现高效的数据检索。 阅读建议:由于文章涉及大量的技术术语和实现细节,建议在阅读过程中对照实际开发项目,结合示例代码进行实践操作,有助于更好地理解和吸收知识点。

Global site tag (gtag.js) - Google Analytics