重看Spring聚焦BeanFactory分析

目录

一、理解BeanFactory

(一)功能性理解

(二)BeanFactory和它的子接口

(三)BeanFactory的实现类

二、BeanFactory根接口

(一)源码展示和理解

(二)基础特性总结

三、HierarchicalBeanFactory(分层 Bean 工厂)

(一)源码展示

(二)理解设计

(三)实际操作分析

四、ListableBeanFactory(可列表的 Bean 工厂)

(一)源码展示

(二)设计选择性列举的目的

(三)案例举例

五、AutowireCapableBeanFactory(可自动装配)

(一)源码展示

(二)设计目的和应用

六、ConfigurableBeanFactory(可配置的 Bean 工厂)

(一)源码展示

(二)思考使用


一、理解BeanFactory

(一)功能性理解

BeanFactory 是 Spring 框架中的一个核心接口,用于管理应用程序中的对象(也称为 bean)。它提供了一种将应用程序组件(如服务、数据源、控制器等)解耦并配置到应用程序中的方式。对 BeanFactory 的初步理解可以简单从以下几个方面来说说:

  1. IoC 容器: BeanFactory 是 Spring 的 IoC 容器之一,IoC(Inverse of Control,控制反转)是一种设计模式,它将对象的创建和管理控制权从代码中转移到了容器中。BeanFactory 作为 IoC 容器的顶层抽象,负责创建、组装、配置和管理 bean 对象。

  2. Bean 定义管理: BeanFactory 负责管理应用程序中的所有 bean 定义。这些 bean 定义通常是通过 XML 文件、注解或 Java 代码进行配置的。BeanFactory 负责解析这些配置信息,并在需要时实例化相应的 bean 对象。

  3. 延迟加载: BeanFactory 支持延迟加载机制,即只有在请求时才会实例化 bean 对象,这样可以提高应用程序的性能和资源利用率。在大型应用程序中,延迟加载可以避免在启动时加载大量的对象,从而加快应用程序的启动速度。

  4. 依赖注入: BeanFactory 实现了依赖注入(DI)机制,它负责解决 bean 之间的依赖关系。通过依赖注入,BeanFactory 可以在创建 bean 对象时自动将其依赖的其他 bean 对象注入到其中,从而实现了对象之间的解耦。

  5. Bean 的作用域管理: BeanFactory 支持不同的 bean 作用域,如 singleton、prototype、request、session 等。通过配置不同的作用域,可以控制 bean 对象的生命周期,并确保在不同的作用域下能够正确地管理 bean 对象的创建和销毁。

总的来说,可以初步理解BeanFactory 为 Spring 框架中负责管理 bean 对象的核心组件,它通过 IoC 容器、延迟加载、依赖注入和作用域管理等机制,实现了对象之间的解耦和灵活配置,从而提高了应用程序的可维护性、可测试性和可扩展性。

(二)BeanFactory和它的子接口

BeanFactory(Bean 工厂)

  • BeanFactory 是 Spring 框架的核心接口之一,负责管理和装配 bean 对象。
  •  Spring IoC 容器的基础,负责创建、查找、注册和管理 bean 对象。

HierarchicalBeanFactory(分层 Bean 工厂)

  • HierarchicalBeanFactory 继承自 BeanFactory 接口,支持创建多级的 bean 工厂层次结构。
  • 层次结构适用父子容器概念,更灵活地管理 bean 对象的生命周期和依赖关系。

ListableBeanFactory(可列表的 Bean 工厂)

  • ListableBeanFactory 继承自 BeanFactory 接口,扩展了对 bean 列表的操作。
  • 允许查询容器中的所有 bean,支持按条件查找和过滤。

AutowireCapableBeanFactory(可自动装配的 Bean 工厂)

  • AutowireCapableBeanFactory 继承自 BeanFactory 接口,增强了自动装配功能。
  • 支持自动装配 bean 的依赖关系,使得我们不需要显式地配置所有的 bean 依赖。

ApplicationContext(应用上下文)

  • ApplicationContext 是 BeanFactory 的一个扩展,提供了更多的应用级功能。
  • 它包括了 BeanFactory 的所有功能,并且提供了国际化、事件发布、资源加载等功能。

ConfigurableBeanFactory(可配置的 Bean 工厂)

  • ConfigurableBeanFactory 继承自 BeanFactory 接口,增强了对 BeanFactory 的配置能力。
  • 允许我们配置 BeanFactory 的各种属性和行为,以满足不同应用场景的需求。

ConfigurableApplicationContext(可配置的应用上下文)

  • ConfigurableApplicationContext 是 ApplicationContext 的扩展,提供了更多的配置选项。
  • 包括了 ApplicationContext 的所有功能,并且支持对 ApplicationContext 进行配置。

ConfigurableListableBeanFactory(可配置且可列表的 Bean 工厂)

  • ConfigurableListableBeanFactory 继承自 ConfigurableBeanFactory 和 ListableBeanFactory 接口,结合了两者的功能。
  • 不仅支持对 BeanFactory 进行配置,还提供了对 bean 列表的操作。

(三)BeanFactory的实现类

BeanFactory的结构体系非常庞大,在 Spring 中,BeanFactory 的实现类是容器的实际执行者,负责解析 bean 的定义、创建 bean 实例以及管理 bean 的生命周期。今天主要针对

二、BeanFactory根接口

BeanFactory 是 Spring 框架中的一个核心接口,用于管理应用程序中的对象(也称为 bean)。它提供了一种将应用程序组件(如服务、数据源、控制器等)解耦并配置到应用程序中的方式。BeanFactory 负责创建、组装、配置和管理 bean 对象。这些 bean 可以通过 XML 文件、注解或 Java 代码进行配置。BeanFactory 还支持延迟加载、依赖注入和作用域管理等功能,以提高应用程序的性能、可维护性和可扩展性。

(一)源码展示和理解

package org.springframework.beans.factory;import org.springframework.beans.BeansException;/*** 根接口,用于定义访问 Spring bean 容器的基本功能。* 这是 Spring IoC 容器的基础接口。*/
public interface BeanFactory {/*** 根据给定的名称获取一个 bean 实例。* @param name 要获取的 bean 的名称* @return bean 实例* @throws BeansException 如果找不到 bean 或 bean 创建过程中发生异常,则抛出 BeansException 异常*/Object getBean(String name) throws BeansException;/*** 检查容器中是否包含具有给定名称的 bean。* @param name 要检查的 bean 的名称* @return 如果容器中包含具有给定名称的 bean,则返回 true;否则返回 false*/boolean containsBean(String name);/*** 检查具有给定名称的 bean 是否为 singleton。* @param name 要检查的 bean 的名称* @return 如果该 bean 是 singleton,则返回 true;否则返回 false* @throws NoSuchBeanDefinitionException 如果找不到具有给定名称的 bean,则抛出 NoSuchBeanDefinitionException 异常*/boolean isSingleton(String name) throws NoSuchBeanDefinitionException;/*** 检查具有给定名称的 bean 是否为 prototype。* @param name 要检查的 bean 的名称* @return 如果该 bean 是 prototype,则返回 true;否则返回 false* @throws NoSuchBeanDefinitionException 如果找不到具有给定名称的 bean,则抛出 NoSuchBeanDefinitionException 异常*/boolean isPrototype(String name) throws NoSuchBeanDefinitionException;/*** 获取具有给定名称的 bean 的类型。* @param name 要获取类型的 bean 的名称* @return bean 的类型* @throws NoSuchBeanDefinitionException 如果找不到具有给定名称的 bean,则抛出 NoSuchBeanDefinitionException 异常*/Class<?> getType(String name) throws NoSuchBeanDefinitionException;/*** 获取具有给定名称的 bean 的别名。* @param name 要获取别名的 bean 的名称* @return bean 的别名数组(如果存在),否则返回空数组* @throws NoSuchBeanDefinitionException 如果找不到具有给定名称的 bean,则抛出 NoSuchBeanDefinitionException 异常*/String[] getAliases(String name) throws NoSuchBeanDefinitionException;}
方法描述
getBean(String name)从容器中获取指定名称(或 ID)的 bean 实例。根据名称查找相应的 bean 定义,并根据需要实例化和初始化 bean 对象。
containsBean(String name)检查容器是否包含具有给定名称的 bean。在内部查找 bean 定义的注册表,并返回相应的结果。
isSingleton(String name)检查具有给定名称的 bean 是否为 singleton。返回 true 表示单例,false 表示非单例。根据定义中的作用域信息确定 bean 是否为 singleton。
isPrototype(String name)检查具有给定名称的 bean 是否为 prototype(原型)。返回 true 表示原型,false 表示非原型。根据定义中的作用域信息确定 bean 是否为 prototype。
getType(String name)获取具有给定名称的 bean 的类型。查找 bean 的定义,并返回相应的 bean 类型信息。
getAliases(String name)获取具有给定名称的 bean 的别名(如果存在)。别名是指在容器中注册的其他名称,可以用来引用相同的 bean 实例。查找 bean 的定义,并返回相应的别名列表。

(二)基础特性总结

特性描述
Bean 实例管理管理应用程序中的各种 bean 实例。提供获取、检查和操作 bean 实例的方法。
Bean 实例化和初始化根据配置信息实例化和初始化 bean。根据配置信息找到相应的 bean 定义,并进行实例化和初始化。
支持不同的作用域支持 singleton(单例)和 prototype(原型)等不同作用域。提供方法检查指定 bean 的作用域,并根据需要获取相应作用域的 bean 实例。
类型信息获取提供方法获取 bean 的类型信息。允许获取指定名称的 bean 的类型。
别名管理支持别名管理,允许为 bean 定义设置多个别名。提供方法获取指定 bean 的所有别名列表。

三、HierarchicalBeanFactory(分层 Bean 工厂)

(一)源码展示

HierarchicalBeanFactory 接口是 BeanFactory 接口的子接口之一,定义了一种层次化的 BeanFactory 结构,可以用于实现 bean 定义的继承和覆盖。以下是 接口的部分源码展示:

public interface HierarchicalBeanFactory extends BeanFactory {// 获取该 BeanFactory 的父级 BeanFactory@NullableBeanFactory getParentBeanFactory();// 判断该 BeanFactory 是否包含给定名称的本地 bean 定义boolean containsLocalBean(@NonNull String name);
}

(二)理解设计

HierarchicalBeanFactory 接口设计的核心理念在于提供一种层次化的 bean 定义管理机制,允许在多个 BeanFactory 之间建立父子关系,实现 bean 定义的继承和覆盖。

  1. 继承与重用:通过允许多个 BeanFactory 之间建立父子关系,子 BeanFactory 可以继承父 BeanFactory 中定义的 bean,从而实现 bean 定义的重用,有利于提高代码的可重用性和可维护性,因为可以将通用的 bean 定义定义在父 BeanFactory 中,而在子 BeanFactory 中只需定义特定的、与父 BeanFactory 不同的 bean。

  2. 覆盖与定制:除了继承外,子 BeanFactory 还可以覆盖父 BeanFactory 中的 bean 定义,以满足特定的业务需求或定制化需求,使得在不同的环境下可以灵活地覆盖和定制 bean 定义,从而实现更高级别的定制化和灵活性。

  3. 解耦与模块化HierarchicalBeanFactory 的设计有助于实现组件之间的解耦和模块化。通过将不同的 bean 定义放置在不同的 BeanFactory 中,可以将不同的组件划分为独立的模块,从而降低组件之间的耦合度,提高代码的可维护性和可扩展性。

  4. 配置灵活性HierarchicalBeanFactory 提供了一种灵活的配置机制,允许在不同层次的 BeanFactory 中进行不同程度的配置。这使得可以根据实际需求灵活地配置不同层次的 BeanFactory,从而满足不同环境下的配置需求,提高了应用程序的适应性和灵活性。

  5. 集成与扩展HierarchicalBeanFactory 设计的灵活性使得可以轻松地集成和扩展现有的 BeanFactory 结构。通过建立新的子 BeanFactory 或者替换现有的父 BeanFactory,可以方便地扩展和定制 BeanFactory 的结构,以满足不同的业务需求或者技术需求。

HierarchicalBeanFactory 的设计充分体现了 Spring 框架的核心理念:依赖注入、松耦合、模块化和可扩展性。通过提供一种层次化的 bean 定义管理机制,使得可以更加灵活地管理和配置 bean,从而实现更加健壮和灵活的应用程序。

(三)实际操作分析

假设我们有一个 Web 应用程序,其中有两个配置文件 applicationContext.xmlwebApplicationContext.xml,分别定义了应用程序的核心组件和 Web 相关的组件。

  • applicationContext.xml 包含了应用程序的核心组件,如数据访问对象、服务、消息处理器等;
  • webApplicationContext.xml 包含了与 Web 相关的组件,如控制器、视图解析器、拦截器等。

在这种情况下,我们可以使用 HierarchicalBeanFactory 来管理这两个配置文件中的 bean 定义。具体实现如下:

public class MainApplicationContext implements HierarchicalBeanFactory {private DefaultListableBeanFactory coreBeanFactory;private DefaultListableBeanFactory webBeanFactory;public MainApplicationContext() {// 初始化核心 BeanFactorycoreBeanFactory = new DefaultListableBeanFactory();XmlBeanDefinitionReader coreReader = new XmlBeanDefinitionReader(coreBeanFactory);coreReader.loadBeanDefinitions("classpath:applicationContext.xml");// 初始化 Web BeanFactory,设置核心 BeanFactory 为父级webBeanFactory = new DefaultListableBeanFactory(coreBeanFactory);XmlBeanDefinitionReader webReader = new XmlBeanDefinitionReader(webBeanFactory);webReader.loadBeanDefinitions("classpath:webApplicationContext.xml");}@Overridepublic BeanFactory getParentBeanFactory() {return coreBeanFactory;}@Overridepublic boolean containsLocalBean(String name) {return coreBeanFactory.containsBeanDefinition(name) || webBeanFactory.containsBeanDefinition(name);}@Overridepublic Object getBean(String name) throws BeansException {try {return webBeanFactory.getBean(name);} catch (NoSuchBeanDefinitionException e) {return coreBeanFactory.getBean(name);}}
}

具体验证可以按实际写测试用例来打印自己相关的配置类。

四、ListableBeanFactory(可列表的 Bean 工厂)

ListableBeanFactory 是 Spring 框架中的另一个重要接口,它是 BeanFactory 接口的子接口之一。与 BeanFactory 不同的是,ListableBeanFactory 不仅可以获取单个的 bean 实例,还可以获取 bean 的列表,并提供了更丰富的检索功能。

(一)源码展示

ListableBeanFactory 接口通过源码中这些方法提供了一种便捷的方式来获取 bean 实例列表,使得应用程序可以更加灵活地管理和操作 bean 实例。通过调用这些方法,可以快速地获取符合条件的 bean 实例,从而方便地进行批量操作、批量注册等操作。

public interface ListableBeanFactory extends BeanFactory {// 根据类型获取所有匹配的 bean 实例<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;// 获取所有 bean 的名称String[] getBeanDefinitionNames();// 根据类型获取所有 bean 的名称String[] getBeanNamesForType(@Nullable Class<?> type);// 根据类型和包含的父级 BeanFactory 获取所有 bean 的名称String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
}

(二)设计选择性列举的目的

设计选择性列举的目的是为了突出重点,集中于最具代表性或最为关键的设计方面,以便更清晰地说明问题或理解设计。通过有选择地列举设计特性,可以避免混淆或过于复杂的描述,使得能够更快速地理解和掌握关键信息。实际应用中可能相对使用的较少,一般我只在不理解有些bean没有生效的时候才会使用下,但是对于其目的而言,不同看源码的人有不同的理解,这里不做区别!

(三)案例举例

简单定义一个服务接口 UserService , AdminUserServiceRegularUserService是其对应的两个实现类。通过 ListableBeanFactory 来验证 Spring 容器中的 bean 实例是否符合预期。

定义 UserService 接口及其两个实现类:

public interface UserService {String getUserType();
}@Component
public class AdminUserService implements UserService {@Overridepublic String getUserType() {return "Admin";}
}@Component
public class RegularUserService implements UserService {@Overridepublic String getUserType() {return "Regular";}
}

创建一个测试类来验证容器中的 bean 实例:

@SpringBootTest
public class UserServiceTest {@Autowiredprivate ListableBeanFactory beanFactory;@Testpublic void testBeanDefinitionNames() {// 获取容器中所有的 bean 名称String[] beanNames = beanFactory.getBeanDefinitionNames();// 验证容器中是否包含了我们定义的两个 bean 实例的名称assertTrue(Arrays.asList(beanNames).contains("adminUserService"));assertTrue(Arrays.asList(beanNames).contains("regularUserService"));}@Testpublic void testGetBeansOfType() {// 根据类型获取容器中所有的 UserService 实例Map<String, UserService> userServiceMap = beanFactory.getBeansOfType(UserService.class);// 验证容器中是否包含了我们定义的两个 UserService 实例assertEquals(2, userServiceMap.size());assertTrue(userServiceMap.containsKey("adminUserService"));assertTrue(userServiceMap.containsKey("regularUserService"));}
}

五、AutowireCapableBeanFactory(可自动装配)

AutowireCapableBeanFactory 是 BeanFactory 接口的子接口之一, 提供了更高级的功能,可以手动实现自动装配、实例化和初始化 bean,以及其他与 bean 相关的操作。

(一)源码展示

AutowireCapableBeanFactory 接口提供了一系列方法,允许手动实现自动装配、实例化和初始化 bean。

public interface AutowireCapableBeanFactory extends BeanFactory {// 将给定的现有 bean 实例应用 autowire bean 属性值void autowireBean(Object existingBean) throws BeansException;// 根据给定 bean 的类别自动装配其属性值Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;// 创建一个新的 bean 实例,并根据定义初始化该 beanObject createBean(Class<?> beanClass) throws BeansException;// 根据给定的 bean 类型和 AutowireMode 创建一个新的 bean 实例Object autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) throws BeansException;// 初始化给定的 bean,应用所有 bean 后处理器Object initializeBean(Object existingBean, String beanName) throws BeansException;// 销毁给定的 bean 实例void destroyBean(Object existingBean);// 在 bean 工厂关闭时调用,用于销毁所有缓存的单例 beanvoid destroySingletons();
}

(二)设计目的和应用

AutowireCapableBeanFactory 接口的设计目的是为了提供更高级的、更灵活的 bean 操作和管理功能。它主要用于那些需要在运行时动态创建、初始化或者自动装配 bean 实例的场景,以及需要更精细地控制 bean 创建过程的场景。

在 Spring 框架中,确实有很多情况下我们不需要直接操作 AutowireCapableBeanFactory 接口。通常情况下,通过配置文件或者注解来定义 bean,并由 Spring 容器负责管理和实例化这些 bean,而无需手动干预 bean 的创建过程。因此,AutowireCapableBeanFactory这个API一般不需要我们去操纵,因为正常开发中不会使用,但如果需要获取AutowireCapableBeanFactory,可以通过ApplicationContext间接获取。

六、ConfigurableBeanFactory(可配置的 Bean 工厂)

ConfigurableBeanFactory 接口提供了一些方法来配置 Bean 工厂的行为和属性,使得我们可以动态地管理和调整 Bean 工厂的配置,从而更好地满足应用程序的需求。通过对 Bean 工厂的配置,可以实现更灵活、更定制化的 Bean 管理方式。

(一)源码展示

ConfigurableBeanFactory 接口提供了一系列操作 Bean 工厂的方法,使得我们可以动态地管理和调整 Bean 工厂的配置。

public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {// 设置父 Bean 工厂void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;// 设置类加载器void setBeanClassLoader(ClassLoader beanClassLoader);// 获取类加载器ClassLoader getBeanClassLoader();// 设置是否缓存 bean 的元数据void setCacheBeanMetadata(boolean cacheBeanMetadata);// 是否缓存 bean 的元数据boolean isCacheBeanMetadata();// 设置 Bean 表达式解析器void setBeanExpressionResolver(BeanExpressionResolver resolver);// 获取 Bean 表达式解析器BeanExpressionResolver getBeanExpressionResolver();// 设置属性编辑器注册表void setPropertyEditorRegistrar(PropertyEditorRegistrar registrar);// 获取属性编辑器注册表PropertyEditorRegistrar getPropertyEditorRegistrar();// 添加 BeanPostProcessor 实例void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);// 注册一个 Scope,用于管理作用域void registerScope(String scopeName, Scope scope);// 获取注册的 ScopeScope getRegisteredScope(String scopeName);// 获取当前 BeanFactory 使用的作用域集合String[] getRegisteredScopeNames();// 注册一个 BeanDefinition,将其添加到 BeanFactory 中void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException;// 移除指定名称的 BeanDefinitionvoid removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;// 获取指定名称的 BeanDefinitionBeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;// 判断是否包含指定名称的 BeanDefinitionboolean containsBeanDefinition(String beanName);// 获取所有的 BeanDefinition 的名称String[] getBeanDefinitionNames();
}

(二)思考使用

对之前的UserService 接口和两个实现类:AdminUserServiceRegularUserService。使用 ConfigurableBeanFactory 来注册 Bean 定义,并配置 Bean 的作用域和属性。

创建一个配置类 BeanConfig,在其中使用 ConfigurableBeanFactory 注册 Bean 定义并配置作用域:

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;@Configuration
public class BeanConfig {@Bean@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) // 设置作用域为原型public UserService regularUserService() {return new RegularUserService();}@Bean@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) // 设置作用域为单例public UserService adminUserService() {return new AdminUserService();}
}

regularUserService() 方法配置了作用域为原型,即每次请求该 Bean 时都会创建一个新的实例;而 adminUserService() 方法配置了作用域为单例,即整个应用程序中只会创建一个实例。创建一个测试类来验证配置是否生效:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
public class UserServiceTest {@Autowiredprivate UserService regularUserService;@Autowiredprivate UserService adminUserService;@Testpublic void testBeanScope() {UserService user1 = regularUserService;UserService user2 = regularUserService;UserService user3 = adminUserService;UserService user4 = adminUserService;// 验证作用域是否生效assertNotSame(user1, user2); // 不同的请求应该返回不同的实例assertSame(user3, user4); // 单例作用域应该返回相同的实例}
}

其他暂时先不做分析应用了。

参考文章

BeanFactory (Spring Framework 6.1.5 API)

Guide to the Spring BeanFactory | Baeldung

https://www.youtube.com/watch?v=tH6rd_OkClM

【Spring源码分析】带你正视一下Spring祖容器之BeanFactory的原理与功能分析(1)_spring_洛神灬殇_InfoQ写作社区

https://www.cnblogs.com/zrtqsk/p/4028453.html

BeanFactory体系结构分析 · 进击的java菜鸟

Spring源码分析之BeanFactory体系结构.md-阿里云开发者社区

Spring-BeanFactory源码分析(一)_setcurrentlyincreation-CSDN博客

Spring源码解析:BeanFactory深入理解-CSDN博客

BeanFactory getBean源码分析 | 奕林的技术博客

深入剖析 Spring 核心数据结构:BeanFactory - "地瓜哥"博客网

Spring的IOC,你真的能解释清楚吗? - 掘金

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

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

相关文章

增强现实(AR)在广告中的力量

The Power of AR in Advertising 写在前面 增强现实&#xff08;AR -Augmented Reality&#xff09;是指借助软件、应用程序和智能手机、平板电脑或耳机等设备&#xff0c;为日常生活添加视觉和音频元素的技术。如今&#xff0c;品牌和广告商可以在营销活动中使用AR&#xff0…

IT运维服务规范标准与实施细则

一、 总则 本部分规定了 IT 运维服务支撑系统的应用需求&#xff0c;包括 IT 运维服务模型与模式、 IT 运维服务管理体系、以及 IT 运维服务和管理能力评估与提升途径。 二、 参考标准 下列文件中的条款通过本部分的引用而成为本部分的条款。凡是注日期的引用文件&#xff0c…

Python通过Ctypes调用C++类,实测有效

文章目录 前言创建vs dll工程添加外部库编辑代码编译测试参考 前言 在软件开发中&#xff0c;有时候需要Python与C相结合&#xff0c;以充分发挥两者的优势 。Python作为一种高级编程语言&#xff0c;具有简洁易读的特点&#xff0c;适用于快速开发和原型设计。而C则是一种性能…

【运维笔记】VM 记录一次centos虚拟机和宿主机之间ping不通的问题

问题描述 环境&#xff1a;centos7&#xff0c;静态ipVM版本&#xff1a;VMware Workstation 16 pro&#xff0c;网络为nat映射模式问题&#xff1a; 一开始&#xff0c;虚拟机可以ping通宿主机&#xff0c;也可以ping通&#xff0c;也可以ping通外网&#xff08;如 ping www.…

38 mars3d 对接地图图层 绘制点线面员

前言 这里主要是展示一下 mars3d 的一个基础的使用 主要是设计 接入地图服务器的 卫星地图, 普通的二维地图, 增加地区标记 基础绘制 点线面园 等等 测试用例 <template><div style"width: 1920px; height:1080px;"><div class"mars3dClas…

②零基础MySQL数据库-MySQL约束

作用 表在设计的时候加入约束的目的就是为了保证表中的记录完整性和有效性&#xff0c;比如用户表有些列的值&#xff08;手机号&#xff09;不能为空&#xff0c;有些列的值&#xff08;身份证号&#xff09;不能重复 分类 主键约束(primary key) PK 自增长约束(auto_increme…

string类的详细模拟实现

string类的模拟实现 文章目录 string类的模拟实现前言1. 类的框架设计2. 构造函数与析构函数3. 拷贝构造与重载赋值运算符函数4. 运算符重载5. 成员函数6. 迭代器的实现7. 非成员函数8. 单元测试总结 前言 ​ 在现代编程中&#xff0c;字符串处理是每个程序员都会遇到的基本任…

家用路由器和企业路由器的区别?

一、家用路由器 家用路由器路由器交换机 它只有一个WAN口和一个LAN口&#xff0c;WAN口接公网一个地址&#xff0c;LAN口接你电脑一个IP地址&#xff0c;完全符合路由器的设计&#xff0c;而因为家里如果用了&#xff0c;说明要接多个电脑&#xff0c;那么如果还需要对每个接口…

pandas的综合练习

事先说明&#xff1a; 由于每次都要导入库和处理中文乱码问题&#xff0c;我都是在最前面先写好&#xff0c;后面的代码就不在写了。要是copy到自己本地的话&#xff0c;就要把下面的代码也copy下。 # 准备工作import pandas as pd import numpy as np from matplotlib impor…

卷积篇 | YOLOv8改进之主干网络中引入可变形卷积DConv

前言:Hello大家好,我是小哥谈。可变形卷积模块是一种改进的卷积操作,它可以更好地适应物体的形状和尺寸,提高模型的鲁棒性。可变形卷积模块的实现方式是在标准卷积操作中增加一个偏移量offset,使卷积核能够在训练过程中扩展到更大的范围,从而实现对尺度、长宽比和旋转等各…

Linux系统下——PS1、PS2、PS3、PS4变量详解

目录 前言 一、PS1变量 1.PS1变量详解 2.PS1变量可用参数 3.彩色提示符 二、PS2变量 三、PS3变量 1.不使用PS3变量 2.使用PS3变量 四、PS4变量 前言 在Linux系统中&#xff0c;PS1、PS2、PS3和PS4是特定的环境变量&#xff0c;它们各自在控制提示符和菜单提示信息…

OceanMind海睿思入选中国信通院《2023高质量数字化转型技术解决方案集》

近日&#xff0c;由中国信息通信研究院“铸基计划”编制的《2023高质量数字化转型技术解决方案集&#xff08;第一版&#xff09;》正式发布。 中新赛克海睿思 凭借卓越的产品力以及广泛的行业实践&#xff0c;成功入选该方案集的数据分析行业技术解决方案。 为促进数字化转型…

RIPGeo代码理解(六)main.py(运行模型进行训练和测试)

​代码链接:RIPGeo代码实现 ├── preprocess.py # 预处理数据集并为模型运行执行IP聚类 ├── main.py # 运行模型进行训练和测试 ├── test.py #加载检查点,然后测试 一、导入各种模块和数据库 import torch.nnfrom lib.utils import * import argparse i…

前端制作计算器

用htmlcssjs完成计算器的基本功能&#xff0c;代码如下&#xff1a; HTML代码 <div id"four"> <div class"evaluator"><div class"input"><input type"text"></div><table><tr><td>…

谧林涓露门禁

原神武器升级材料谧林涓露和门禁好像聂。 difference(){union(){cylinder(2, 10,10, $fn365);hull(){translate([15,0,0])cylinder(1,2,2,$fn365);cylinder(1,10,10,$fn365);}}translate([15,0,-1])cylinder(4,1,1,$fn365); }

modelsim与quartus联合仿真ROM读不出数据

modelsim与quartus联合仿真ROM没有数据被读出&#xff0c;很是纳闷。 原因&#xff1a;hex或者mif文件放的不对&#xff0c;放在与db放在同一个文件夹下。modelsim在这个目录查找mif文件或hex。 这是我遇到的问题。当然可能还有其他的问题&#xff1a; 1、mif文件的格式不对&a…

双系统安装03--在已有麒麟KOS基础上安装Windows10

原文链接&#xff1a;双系统安装03–在已有麒麟KOS基础上安装Windows10 Hello&#xff0c;大家好啊&#xff01;继我们之前讨论的关于双系统安装的系列文章之后&#xff0c;今天我将带给大家这个系列的第三篇——在已有的麒麟桌面操作系统上安装Windows 10。对于想要在使用麒麟…

docker安装ES7.1.1(单机版)+ik分词器+es-head可视化

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 Elasticsearch 是一…

力扣236 二叉树的最近公共祖先 Java版本

文章目录 题目描述代码 题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&…

FlyControls 是 THREE.js 中用于实现飞行控制的类,它用于控制摄像机在三维空间中的飞行。

demo演示地址 FlyControls 是 THREE.js 中用于实现飞行控制的类&#xff0c;它用于控制摄像机在三维空间中的飞行。 入参&#xff1a; object&#xff1a;摄像机对象&#xff0c;即要控制的摄像机。domElement&#xff1a;用于接收用户输入事件的 HTML 元素&#xff0c;通常…