Spring Boot 面试题——自动装配

目录

  • Spring Boot 中的自动装配是指什么?解决了什么问题?
  • Spring Boot 自动装配的流程有哪些?
  • Spring Boot 中实现自动装配的原理是什么?
  • Spring 中的 ConfigurationClassPostProcessor 类有什么作用?
  • Spring Boot 自动装配涉及的核心源码有哪些?
    • Spring Boot 应用程序启动类
    • 执行 SpringApplication 类中的构造方法
    • 执行 SpringApplication 类中的 run 方法
      • 执行 run 方法中的 prepareContext 方法
      • 执行 run 方法中的 refreshContext 方法
  • META-INF/spring.factories 文件有什么作用?

Spring Boot 中的自动装配是指什么?解决了什么问题?

(1)在 Spring Boot 中,自动装配是一种机制,它允许开发者无需显式地配置依赖项或组件,而是通过约定和默认值来实现自动配置。通过这种方式,Spring Boot能够简化开发过程并提高开发效率。

(2)自动装配能够解决以下问题:

  • 依赖管理:Spring Boot 的自动配置机制能够根据项目的需求自动引入所需的依赖项,而无需手动维护和管理依赖关系。
  • 配置管理:Spring Boot 提供了一种简化的配置方式,可以根据约定和默认值自动装配应用程序所需的配置参数,减少了繁琐的配置过程。
  • 组件注册:Spring Boot 可以自动扫描项目中的组件,并将其注册为 Spring 容器中的 Bean,使得这些组件能够被其他组件自动注入和使用。
  • 功能扩展:Spring Boot 提供了大量的自动配置模块,可以根据项目的需要自动启用或禁用某些功能,实现快速开发和定制。

(3)总的来说,自动装配的实现就是为了从 META-INF/spring.factories 文件中加载并创建对应的 Bean 对象,并且将它们交给 Spring 容器来进行统一管理。

Spring Boot 自动装配的流程有哪些?

(1)Spring Boot 的自动装配流程如下:

  • Spring Boot 启动时,会扫描并加载所有的类路径下的 META-INF/spring.factories 文件,并读取其中的配置信息。
  • 通过读取 spring.factories 文件中 org.springframework.boot.autoconfigure.EnableAutoConfiguration 键对应的值,获取所有需要自动装配的配置类
  • Spring Boot 根据这些配置类的信息,按照特定的顺序进行自动装配。关键的自动装配注解有 @EnableAutoConfiguration@SpringBootApplication
  • 自动装配过程中,Spring Boot 会根据配置类中的条件注解(以 @ConditionalOnXXX 开头)来进行判断,决定是否装配某个组件。
  • 自动装配过程还会考虑用户自定义的配置,可以通过在 application.propertiesapplication.yml 文件中添加配置信息,来覆盖默认的自动装配行为
  • 最后,Spring Boot 会根据自动装配的结果和应用的需要,创建相应的 Bean,并将其注册到 Spring 的应用上下文中,供应用程序使用

(2)总的来说,Spring Boot 的自动装配机制通过扫描配置文件,加载配置类,并根据配置类和条件进行自动装配,从而简化了应用程序的配置工作。

Spring Boot 中实现自动装配的原理是什么?

(1)Spring Boot 中实现自动装配的原理入如下:

  • 在启动类中的执行 SpringApplication.run 方法,并且将启动类的 class 对象作为参数传入其中,方便 Spring Boot 能够扫描该类所在的包以及其子包,并解析该启动类上的注解。
  • 加载 spring.factories:当启动 Spring Boot 应用程序的时候,会先创建 SpringApplication 对象,并且在对象的构造方法中会进行一些初始化工作,最主要的是判断当前应用程序的类型以及设置初始化器和监听器,并且在这个过程中会加载整个应用程序中 META-INF/spring.factories 文件中的配置类,将文件的内容放到缓存对象中,方便后续获取。
  • 执行两个关键方法SpringApplication 对象创建完成之后,开始执行 run 方法,来完成整个启动,启动过程中有两个非常重要的方法,分别是 prepareContext 方法和 refreshContext 方法,在这两个关键步骤中完整了自动装配的核心功能:
    • prepareContext 方法中主要完成的是对上下文对象的初始化操作,包括了属性值的设置,比如环境对象,在整个过程中有一个非常重要的方法,叫做 load,它主要完成一件事,将当前启动类做为一个 beanDefinition 对象注册到 registry 中,方便后续在进行 BeanFactoryPostProcessor 调用执行的时候,找到对应的主类,来完成 @SpringBootApplicaiton 等注解的解析工作;
    • refreshContext 方法中会进行整个容器的刷新过程,会调用 AbstractApplicationContext 类中的 refresh 方法,该方法中有 13 个非常关键的方法,来完成整个 Spring 应用程序的启动。在自动装配过程中,会调用 13 个方法中的 invokeBeanFactoryPostProcessor 方法,此方法主要是对 ConfigurationClassPostProcessor 类的处理,该类实现了 BeanDefinitionRegisterProcessor 接口(BeanFactoryPostProcessor 的子接口)。在调用的时候会调用该类中的 postProcessBeanDefinitionRegistry 方法,该方法解析处理各种注解,包含 @PropertySource@ComponentScan@ComponentScans@Bean@lmport 等注解,最主要的是 @lmport 注解的解析:
      • 在解析 @lmport 注解的时候,会有一个 getImports 的方法,从主类开始递归解析注解,把所有包含 @lmport 的注解都解析到,然后在processImport 方法中对 Import 的类进行分类,其中 AutoConfigurationImportSelect 归属于 ImportSelect 的子类,在后续过程中会调用 deferredlmportSelectorHandler 中的 process 方法,来完整 EnableAutoConfiguration 的加载;

Spring 中的 ConfigurationClassPostProcessor 类有什么作用?

(1)在 Spring 中,ConfigurationClassPostProcessor类是一个重要的后置处理器,它实现了 BeanDefinitionRegisterProcessor 接口(BeanFactoryPostProcessor 的子接口,具体关系如下图所示),其作用是处理带有 @Configuration 注解的配置类。具体而言,ConfigurationClassPostProcessor 类完成以下几个主要的任务:

  • 将配置类转换为BeanDefinition对象:当Spring Boot应用启动时,ConfigurationClassPostProcessor会检查所有带有@Configuration注解的配置类,并将它们转换为BeanDefinition对象。这个过程包括解析配置类中的各种元数据,如 Bean 的定义、作用域、依赖关系等,并将其存储在Spring的BeanDefinition注册表中。
  • 处理配置类中的特殊注解:ConfigurationClassPostProcessor 还会处理配置类中的一些特殊注解,比如@Conditional@Import@PropertySource 等。它会根据这些注解的定义,对应进行处理并最终影响 Bean 的创建和配置。
  • 处理配置类中的 @Bean 注解:配置类中通常使用 @Bean 注解来定义 Bean 的创建和配置,而ConfigurationClassPostProcessor 会解析这些 @Bean 方法,将其转换为对应的 BeanDefinition 对象,并存储在 Spring 容器的 Bean 定义注册表中。这样,当应用程序需要该 Bean 时,Spring 容器就可以根据这些注册信息进行创建和管理。

(2)总体来说,ConfigurationClassPostProcessor 类在 Spring Boot 中起到了非常重要的作用。它负责解析和处理配置类,将其转换为Spring 容器可以理解的 BeanDefinition 对象,并最终完成 Bean 的创建和配置过程。通过该后置处理器,Spring Boot 可以高效地管理和配置应用程序中的各种 Bean。

在这里插入图片描述

Spring Boot 自动装配涉及的核心源码有哪些?

Spring Boot 应用程序启动类

执行 SpringApplication 中的 run 方法,并且将启动类的 class 对象作为参数传入其中,方便 Spring Boot 能够扫描该类所在的包以及其子包,并解析该启动类上的注解。

@SpringBootApplication
public class ContentApplication {public static void main(String[] args) {SpringApplication.run(ContentApplication.class, args);}
}

执行 SpringApplication 类中的构造方法

SpringApplication 类的构造方法中会进行一些初始化工作,最重要的是加载 spring.factories 文件:

public class SpringApplication {//...public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {return run(new Class<?>[] { primarySource }, args);}public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {return new SpringApplication(primarySources).run(args);}public SpringApplication(Class<?>... primarySources) {this(null, primarySources);}//执行 SpringApplication 类中的构造方法@SuppressWarnings({ "unchecked", "rawtypes" })public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));this.webApplicationType = WebApplicationType.deduceFromClasspath();//设置初始化器,此过程中会加载 spring.factories 文件setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));//设置监听器setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));this.mainApplicationClass = deduceMainApplicationClass();}private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {return getSpringFactoriesInstances(type, new Class<?>[] {});}	private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {ClassLoader classLoader = getClassLoader();// Use names and ensure unique to protect against duplicates// loadFactoryNames 方法中会加载 spring.factories 文件,具体执行步骤在 SpringFactoriesLoader 类中Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);AnnotationAwareOrderComparator.sort(instances);return instances;}
}
public final class SpringFactoriesLoader {//...public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {String factoryTypeName = factoryType.getName();return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());}private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {MultiValueMap<String, String> result = cache.get(classLoader);if (result != null) {return result;}try {	//下面的 FACTORIES_RESOURCE_LOCATION 即为 spring.factories 文件的路径Enumeration<URL> urls = (classLoader != null ?classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));result = new LinkedMultiValueMap<>();while (urls.hasMoreElements()) {URL url = urls.nextElement();UrlResource resource = new UrlResource(url);Properties properties = PropertiesLoaderUtils.loadProperties(resource);for (Map.Entry<?, ?> entry : properties.entrySet()) {String factoryTypeName = ((String) entry.getKey()).trim();for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {result.add(factoryTypeName, factoryImplementationName.trim());}}}cache.put(classLoader, result);return result;}catch (IOException ex) {throw new IllegalArgumentException("Unable to load factories from location [" +FACTORIES_RESOURCE_LOCATION + "]", ex);}}
}

执行 SpringApplication 类中的 run 方法

SpringApplication 类中 run 方法是整个过程的核心方法。

public class SpringApplication {//...public ConfigurableApplicationContext run(String... args) {	StopWatch stopWatch = new StopWatch();stopWatch.start();//上下文对象,保存当前操作前后的属性信息ConfigurableApplicationContext context = null;Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();configureHeadlessProperty();SpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting();try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);configureIgnoreBeanInfo(environment);Banner printedBanner = printBanner(environment);context = createApplicationContext();exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,new Class[] { ConfigurableApplicationContext.class }, context);//***准备上下文***prepareContext(context, environment, listeners, applicationArguments, printedBanner);//***刷新上下文***refreshContext(context);afterRefresh(context, applicationArguments);stopWatch.stop();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}listeners.started(context);callRunners(context, applicationArguments);}catch (Throwable ex) {handleRunFailure(context, ex, exceptionReporters, listeners);throw new IllegalStateException(ex);}try {listeners.running(context);}catch (Throwable ex) {handleRunFailure(context, ex, exceptionReporters, null);throw new IllegalStateException(ex);}return context;}
}

执行 run 方法中的 prepareContext 方法

public class SpringApplication {//...private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {context.setEnvironment(environment);postProcessApplicationContext(context);applyInitializers(context);listeners.contextPrepared(context);if (this.logStartupInfo) {logStartupInfo(context.getParent() == null);logStartupProfileInfo(context);}// Add boot specific singleton beansConfigurableListableBeanFactory beanFactory = context.getBeanFactory();beanFactory.registerSingleton("springApplicationArguments", applicationArguments);if (printedBanner != null) {beanFactory.registerSingleton("springBootBanner", printedBanner);}if (beanFactory instanceof DefaultListableBeanFactory) {((DefaultListableBeanFactory) beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}if (this.lazyInitialization) {context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());}// Load the sourcesSet<Object> sources = getAllSources();Assert.notEmpty(sources, "Sources must not be empty");/*(1) sources 中保存了启动类 ContentApplication 的相关信息(2) laod 方法将当前启动类做为一个 BeanDefinition 对象注册到 registry 中,方便后面解析到启动类上的注解*/load(context, sources.toArray(new Object[0]));listeners.contextLoaded(context);}protected void load(ApplicationContext context, Object[] sources) {if (logger.isDebugEnabled()) {logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));}BeanDefinitionLoader loader = createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);if (this.beanNameGenerator != null) {loader.setBeanNameGenerator(this.beanNameGenerator);}if (this.resourceLoader != null) {loader.setResourceLoader(this.resourceLoader);}if (this.environment != null) {loader.setEnvironment(this.environment);}loader.load();}
}

执行 run 方法中的 refreshContext 方法

public class SpringApplication {//...private void refreshContext(ConfigurableApplicationContext context) {if (this.registerShutdownHook) {try {context.registerShutdownHook();}catch (AccessControlException ex) {// Not allowed in some environments.}}refresh((ApplicationContext) context);}
}

上面的方法会调用到 AbstractApplicationContext 类中的 refresh 方法:

public abstract class AbstractApplicationContext extends DefaultResourceLoaderimplements ConfigurableApplicationContext {//...@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.prepareRefresh();// Tell the subclass to refresh the internal bean factory.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.registerBeanPostProcessors(beanFactory);// Initialize message source for this context.initMessageSource();// Initialize event multicaster for this context.initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.onRefresh();// Check for listener beans and register them.registerListeners();// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();}}}
}

META-INF/spring.factories 文件有什么作用?

(1)META-INF/spring.factories 文件是在使用 Spring 框架的项目中常见的一个文件,它用于进行 Spring 框架的扩展和自动装配。spring.factories 文件采用键值对的形式,其中键表示一个接口或抽象类的全限定名,值表示具体的实现类或配置类的全限定名。这个文件的作用是告诉 Spring 框架在启动时自动加载和注册这些实现类或配置类,从而进行自动装配。

(2)下面是 Spring Boot 框架中 spring.factories 文件的部分内容:

# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition//...

在这里插入图片描述

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

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

相关文章

识别flink的反压源头

背景 flink中最常见的问题就是反压&#xff0c;这种情况下我们要正确的识别导致反压的真正的源头&#xff0c;本文就简单看下如何正确识别反压的源头 反压的源头 首先我们必须意识到现实中轻微的反压是没有必要去优化的&#xff0c;因为这种情况下是由于偶尔的流量峰值,Task…

unity 从UI上拖出3D物体,(2D转3D)

效果展示&#xff1a; 2D转3D视频 UI结构 UI组件挂载 UI结构 这个脚本挂载到 3D物体身上 using DG.Tweening; using System.Collections; using System.Collections.Generic; using UnityEngine;public class DragGame : MonoBehaviour {[HideInInspector]public bool isDrag…

Redis之 redis.config配置文件

文章目录 前言一、基本配置1.单位2.包含3.网络配置4.通用5.快照6.安全7.限制8.仅追加模式 二、总体主要介绍总结 前言 行家一出手&#xff0c;就知有没有&#xff0c;让一起学习redis.config配置文件。 一、基本配置 Redis 的配置文件位于 Redis 安装目录下&#xff0c;文件名…

2023李宏毅机器学习HW05样例代码中文注释版

这里只是 2023 李宏毅机器学习 HW05 样例代码的中文注释版的分享&#xff0c;下面的内容绝大部分是样例代码&#xff0c;补充了小部分函数的功能解释&#xff0c;没有做函数功能上的修改&#xff0c;是 Simple baseline 版本。 notebook 代码下载: [EN] [ZH] 文章目录 作业描述…

软件测试/测试开发丨利用ChatGPT 生成自动化测试脚本

点此获取更多相关资料 简介 自动化测试脚本可以模拟用户与应用程序的交互&#xff0c;例如点击按钮、输入数据、导航到不同的页面等等&#xff0c;以验证应用程序的正确性、性能和稳定性。 自动化测试在回归测试、冒烟测试等测试流程中都可以极大地起到节省时间、节省人力的作…

优先队列----数据结构

概念 不知道你玩过英雄联盟吗&#xff1f;英雄联盟里面的防御塔会攻击离自己最近的小兵&#xff0c;但是如果有炮车兵在塔内&#xff0c;防御塔会优先攻击炮车&#xff08;因为炮车的威胁性更大&#xff09;&#xff0c;只有没有兵线在塔内时&#xff0c;防御塔才会攻击英雄。…

Charles小白新手入门教程

最近系统地重温了下Charles的各种功能&#xff0c;根据小破站上百里老师的讲解&#xff0c;做了一些笔记&#xff0c;对于Charles入门小白&#xff0c;多少会有点帮助&#xff0c; 下面就把分享给大家~ 一、Charles介绍 1、Charles简介 是基于http和https的代理服务器。 2、…

香港服务器不稳定的几种情况

​  近年来&#xff0c;随着互联网的迅猛发展&#xff0c;香港作为一个重要的网络枢纽地区&#xff0c;扮演着连接中国内地和国际网络的重要角色。一些用户表示在使用香港服务器时可能会遇到不稳定的情况&#xff0c;导致访问困难、加载缓慢甚至无法连接。 为什么香港服务器会…

【广州华锐互动】军用飞机VR实战训练系统

随着科技的飞速发展&#xff0c;虚拟现实(VR)技术为军事训练带来了前所未有的机遇。军用飞机VR实战训练系统&#xff0c;正是在这一背景下应运而生的一种创新的训练方法。该系统利用先进的虚拟现实技术&#xff0c;为飞行员提供真实且逼真的模拟飞行环境&#xff0c;使之能够在…

如何将极狐GitLab 漏洞报告导出为 HTML 或 PDF 格式或导出到 Jira

目录 导出为 HTML/PDF 将漏洞信息导出到 Jira 参考资料 极狐GitLab 的漏洞报告功能可以让开发人员在统一的平台上面管理代码&#xff0c;对其进行安全扫描、管理漏洞报告并修复漏洞。但有些团队更喜欢使用类似 Jira 的单独工具来管理他们的安全漏洞。他们也可能需要以易于理…

3.网络之UDP

UDP协议 文章目录 UDP协议1. UDP概述2. UDP报文格式3. UDP传输限制4. UDP校验和4.1 CRC 循环冗余校验算法4.2 md5 校验算法 1. UDP概述 UDP&#xff08;UserDatagramProtocol&#xff09;是一个简单的面向消息的传输层协议&#xff0c;尽管UDP提供标头和有效负载的完整性验证&a…

机器学习---支持向量机的初步理解

1. SVM的经典解释 改编自支持向量机解释得很好 |字节大小生物学 (bytesizebio.net) 话说&#xff0c;在遥远的从前&#xff0c;有一只贪玩爱搞破坏的妖怪阿布劫持了善良美丽的女主小美&#xff0c;智勇双全 的男主大壮挺身而出&#xff0c;大壮跟随阿布来到了妖怪的住处&…

unraid 安装并设置 zerotier 内网穿透安装 unraid 局域网内其他设备

Read Original 最近看了以下两个文章&#xff0c;感谢发布的各种精彩文章&#xff0c;让我受益匪浅。OPENWRT 的固件在设置了&#xff0c;【自动允许客户端 NAT】后&#xff0c;可以直接访问局域网其他设备&#xff0c;而我 unraid 部署 zerotier 后&#xff0c;只能访问 unra…

STM32:AHT20温湿度传感器驱动程序开发

注&#xff1a;温湿度传感器AHT20数据手册.pdf http://www.aosong.com/userfiles/files/AHT20%E4%BA%A7%E5%93%81%E8%A7%84%E6%A0%BC%E4%B9%A6(%E4%B8%AD%E6%96%87%E7%89%88)%20B1.pdf 一、分析AHT数据手册文档 (1).准备工作 1.新建工程。配置UART2 2.配置I2C1为I2C标准模式&…

C++笔记之实现多态的所有方法

C笔记之实现多态的所有方法 文章目录 C笔记之实现多态的所有方法1.C中多态是是什么&#xff1f;请用简洁准确的话描述2.虚函数实现多态2.1.虚函数&#xff08;Virtual Functions&#xff09;2.2.纯虚函数&#xff08;Pure Virtual Functions&#xff09;2.3.虚析构函数&#xf…

Linux基础环境开发工具的使用(yum,vim,gcc,g++)

Linux基础环境开发工具的使用[yum,vim,gcc,g] 一.yum1.yum的快速入门1.yum安装软件2.yum卸载软件 2.yum的生态环境1.操作系统的分化2.四个问题1.服务器是谁提供的呢?2.服务器上的软件是谁提供的呢?3.为什么要提供呢?4.yum是如何得知目标服务器的地址和下载链接呢?5.软件源 …

安全第一!速卖通测评补单稳定的系统注意事项大盘点

对新卖家而言&#xff0c;测评并非可耻之事&#xff0c;反而是无法起步、耗费自身时间才是真正的可耻。由于速卖通新店几乎无法获得任何活动的支持&#xff0c;流量也基本没有&#xff0c;因此要在90天内达成60单的业绩对于许多卖家来说都是一项挑战。因此&#xff0c;通过快速…

一天掌握python爬虫【基础篇】 涵盖 requests、beautifulsoup、selenium

大家好&#xff0c;我是python222小锋老师。前段时间卷了一套 Python3零基础7天入门实战 以及1小时掌握Python操作Mysql数据库之pymysql模块技术 近日锋哥又卷了一波课程&#xff0c;python爬虫【基础篇】 涵盖 requests、beautifulsoup、selenium&#xff0c;文字版视频版。1…

SpringBoot热部署2023最新版IDEA详细步骤

1、在pom.xml中配置依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional> </dependency>注意&#xff1a; 依赖放在标签里面 加入依赖后…

再学一点mybatis(原理分析)

文章目录 [TOC](文章目录) 一、mybatis是什么&#xff1f;1. Mybatis的特点以及优缺点 二、mybatis架构1.基本架构2.重要组件 三、原理1. SQL解析2. Mapper接口3. 动态代理4. SQL执行4.1 Executor4.2 StatementHandler4.3 ParameterHandler4.4 ResultHandler 文章内容有点长&am…