spring5.x-IOC模块源码学习

news2025/7/10 22:13:17

上文:spring5.x介绍及搭配spring源码阅读环境


IOC介绍

    spring的IOC和DI

演示案例

com.hong.model.User

package com.hong.model;

import org.springframework.stereotype.Component;

import java.io.Serializable;

/**
* @ClassName User
* @Description 用户
* @Author csh
* @Date 2023/1/13 14:27
*/
@Component
    public class User{
        private String userName;
        private int age;
        private String nickName;

        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public String getNickName() {
            return nickName;
        }

        public void setNickName(String nickName) {
            this.nickName = nickName;
        }

        public User() {
            this.userName = "hong";
        }
    }

com.hong.ioc.IocConfig

package com.hong.ioc;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
* @ClassName IocConfig
* @Description ioc配置
* @Author csh
* @Date 2023/1/13 14:29
*/
@Configuration
    @ComponentScan(basePackages = {"com.hong"})
    public class IocConfig {
    }

com.hong.ioc.IocSourceStudy

package com.hong.ioc;

import com.hong.model.User;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
* @ClassName IocSourceStudy
* @Description ioc学习
* @Author csh
* @Date 2023/1/13 14:26
*/
public class IocSourceStudy {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(IocConfig.class);
        User user = applicationContext.getBean("user",User.class);
        System.out.println(user.getUserName());
    }
}

执行结果

16:12:26: Executing task 'IocSourceStudy.main()'...

    > Task :buildSrc:compileJava UP-TO-DATE
    > Task :buildSrc:compileGroovy NO-SOURCE
    > Task :buildSrc:pluginDescriptors UP-TO-DATE
    > Task :buildSrc:processResources UP-TO-DATE
    > Task :buildSrc:classes UP-TO-DATE
    > Task :buildSrc:jar UP-TO-DATE
    > Task :buildSrc:assemble UP-TO-DATE
    > Task :buildSrc:pluginUnderTestMetadata UP-TO-DATE
    > Task :buildSrc:compileTestJava NO-SOURCE
    > Task :buildSrc:compileTestGroovy NO-SOURCE
    > Task :buildSrc:processTestResources NO-SOURCE
    > Task :buildSrc:testClasses UP-TO-DATE
    > Task :buildSrc:test NO-SOURCE
    > Task :buildSrc:validateTaskProperties UP-TO-DATE
    > Task :buildSrc:check UP-TO-DATE
    > Task :buildSrc:build UP-TO-DATE
    > Task :spring-core:cglibRepackJar UP-TO-DATE
    > Task :spring-aop:processResources UP-TO-DATE
    > Task :spring-core:objenesisRepackJar UP-TO-DATE
    > Task :spring-hong-testing:processResources NO-SOURCE
    > Task :spring-expression:processResources UP-TO-DATE
    > Task :spring-beans:processResources UP-TO-DATE
    > Task :spring-core:processResources UP-TO-DATE
    > Task :spring-context:processResources UP-TO-DATE
    > Task :spring-instrument:compileJava UP-TO-DATE
    > Task :spring-instrument:processResources NO-SOURCE
    > Task :spring-instrument:classes UP-TO-DATE
    > Task :spring-instrument:jar UP-TO-DATE
    > Task :kotlin-coroutines:compileKotlin UP-TO-DATE
    > Task :kotlin-coroutines:compileJava NO-SOURCE
    > Task :kotlin-coroutines:processResources NO-SOURCE
    > Task :kotlin-coroutines:classes UP-TO-DATE
    > Task :spring-jcl:compileJava UP-TO-DATE
    > Task :kotlin-coroutines:inspectClassesForKotlinIC UP-TO-DATE
    > Task :spring-jcl:processResources UP-TO-DATE
    > Task :spring-jcl:classes UP-TO-DATE
    > Task :kotlin-coroutines:jar UP-TO-DATE
    > Task :spring-jcl:jar UP-TO-DATE
    > Task :spring-core:compileKotlin UP-TO-DATE
    > Task :spring-core:compileJava UP-TO-DATE
    > Task :spring-core:classes UP-TO-DATE
    > Task :spring-core:inspectClassesForKotlinIC UP-TO-DATE
    > Task :spring-core:jar UP-TO-DATE
    > Task :spring-expression:compileKotlin UP-TO-DATE
    > Task :spring-expression:compileJava UP-TO-DATE
    > Task :spring-expression:classes UP-TO-DATE
    > Task :spring-expression:inspectClassesForKotlinIC UP-TO-DATE
    > Task :spring-expression:jar UP-TO-DATE
    > Task :spring-beans:compileGroovy UP-TO-DATE
    > Task :spring-beans:compileKotlin UP-TO-DATE
    > Task :spring-beans:compileJava NO-SOURCE
    > Task :spring-beans:classes UP-TO-DATE
    > Task :spring-beans:inspectClassesForKotlinIC UP-TO-DATE
    > Task :spring-beans:jar UP-TO-DATE
    > Task :spring-aop:compileJava UP-TO-DATE
    > Task :spring-aop:classes UP-TO-DATE
    > Task :spring-aop:jar UP-TO-DATE
    > Task :spring-context:compileKotlin UP-TO-DATE
    > Task :spring-context:compileJava UP-TO-DATE
    > Task :spring-context:compileGroovy NO-SOURCE
    > Task :spring-context:classes UP-TO-DATE
    > Task :spring-context:inspectClassesForKotlinIC UP-TO-DATE
    > Task :spring-context:jar UP-TO-DATE
    > Task :spring-hong-testing:compileJava
    > Task :spring-hong-testing:classes

    > Task :spring-hong-testing:IocSourceStudy.main()
    hong

    BUILD SUCCESSFUL in 15s
    35 actionable tasks: 2 executed, 33 up-to-date
    16:12:42: Task execution finished 'IocSourceStudy.main()'.

相关依赖图

26c2e4eaf762ed8dfa6c43d315619cff.png

IOC的加载过程

691b245e8b33c58b9a0a1022c8310c6b.png

实例化容器:AnnotationConfigApplicationContext

org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(java.lang.Class<?>...)

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    //调用无参构造方法 进行实例化AnnotationConfigApplicationContext
    this();
    //注册类 注册分两种一种是配置文件 比如.xml 还有一种就是指定的.class(bean)
    register(componentClasses);
    //刷新
    refresh();
}

1.调用构造方法中的this();

org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext()

public AnnotationConfigApplicationContext() {
    //初始化bean读取器
    this.reader = new AnnotatedBeanDefinitionReader(this);
    //初始化类扫描器
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

1.1 this的具体实现

org.springframework.context.annotation.AnnotatedBeanDefinitionReader#AnnotatedBeanDefinitionReader(org.springframework.beans.factory.support.BeanDefinitionRegistry, org.springframework.core.env.Environment)

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    Assert.notNull(environment, "Environment must not be null");
    this.registry = registry;
    //@Conditional的实始化
    this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
    //初始化相关组件 比如 @Order @lazy 与@Qualifier注解 @Autowired与@Value注解的 等 
    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
1.1.1 初始化相关组件 比如 @Order @lazy 与@Qualifier注解  @Autowired与@Value注解的 等

org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
    BeanDefinitionRegistry registry, @Nullable Object source) {
    //@EventListener的初始化
    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
    if (beanFactory != null) {
        //解析@Order 初始化
        if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
            beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
        }
        //解析@lazy 与@Qualifier注解 初始化
        if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
            beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        }
    }

    Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    //新增解析配置类的处理器
    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
    //新增处理@Autowired与@Value注解的后置处理器
    if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 检查是否支持JSR-250 新增处理@Resource 注解的后置处理器
    if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 检查是否支持JPA,将启用JPA注解支持
    if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition();
        try {
            def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                                                AnnotationConfigUtils.class.getClassLoader()));
        }
        catch (ClassNotFoundException ex) {
            throw new IllegalStateException(
                "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
        }
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
    //监听器的支持@EventListener注解
    if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
    }
    //指定监听器的默认实现类
    if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
                     }

                     return beanDefs;
                     }

2.register(componentClasses); 的实现

bab6471e1d7e37d9dc07032309f87376.png

org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
      @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
      @Nullable BeanDefinitionCustomizer[] customizers) {
    //对bean进行封装
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    //如果为空或类型不一致则直接返回
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
      return;
    }
    //设置bean的回调
    abd.setInstanceSupplier(supplier);
    //解析bean的作用域 有两种类型如下:
    // @Scope("prototype") 原类型
    // @Scope("singleton"),单态类型 默认不配的情况下是这种
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    //设置作用域
    abd.setScope(scopeMetadata.getScopeName());
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    //主要用于判断这个类有没有包含 Lazy Primary DependsOn Role Description 这些注释或属性有的话进行设置。
    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
    //如果不为空 匹配是 @Primary 或@Lazy 或@Qualifier 都进行初始化设置
    if (qualifiers != null) {
      for (Class<? extends Annotation> qualifier : qualifiers) {
        if (Primary.class == qualifier) {
          abd.setPrimary(true);
        }
        else if (Lazy.class == qualifier) {
          abd.setLazyInit(true);
        }
        else {
          abd.addQualifier(new AutowireCandidateQualifier(qualifier));
        }
      }
    }
    //如果存在个性化配置进行增加
    if (customizers != null) {
      for (BeanDefinitionCustomizer customizer : customizers) {
        customizer.customize(abd);
      }
    }
    //进行BeanDefinition的封装
    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    //根据作用域创建代理对象。
    //默认NO 是不创建代理对象 当然还有JDK和CGLib
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    //最后注册成bean对象
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
  }
3.refresh()刷新的实现;

org.springframework.context.support.AbstractApplicationContext#refresh

@Override
  public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
      // 为刷新准备上下文,保存容器启动时间和设置关闭状态为否及运行状态启动等初始化工作
      prepareRefresh();

      // 告诉子类刷新内部bean工厂。初始化bean工厂
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      //准备在此上下文中使用的bean工厂。
      prepareBeanFactory(beanFactory);

      try {
        // 允许在上下文子类中对bean工厂进行后处理。(前置处理器)
        postProcessBeanFactory(beanFactory);

        //调用上下文中注册为bean的工厂处理器。(为beanFactory注册的事件处理器)
        invokeBeanFactoryPostProcessors(beanFactory);

        //调用bean的后置处理器
        registerBeanPostProcessors(beanFactory);

        // 初始化国际化资源处理器
        initMessageSource();

        //创建事件多播器
        initApplicationEventMulticaster();

        // 初始化扩展的自定义插件 比如tomcat
        onRefresh();

        // 检查侦听器bean并注册它们。
        registerListeners();

        //实例化所有剩余的(非lazy-init)单例。
        finishBeanFactoryInitialization(beanFactory);

        //最后容器刷新 发布刷新后的事件
        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();

        // 重置标记
        cancelRefresh(ex);

        // Propagate exception to caller.
        throw ex;
      }

      finally {
        //重置单例bean元数据(清空缓存)
        resetCommonCaches();
      }
    }
  }

prepareBeanFactory的实现

org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 告诉内部bean工厂使用上下文的类装入器等。
    beanFactory.setBeanClassLoader(getClassLoader());
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // 使用上下文回调来配置bean工厂。
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

    // 在普通工厂中,BeanFactory接口未注册为可解析类型。
    // MessageSource作为bean注册(并找到用于自动装配)。
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    //将早期的后置处理器注册为应用监听器,用于检测内部bean。
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // 检查存在loadTimeWeaver 的类型则进行设置
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      //为类型匹配设置一个临时的ClassLoader。
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    // 注册默认环境bean。
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
  }

最后

    以上就是大致IOC的初始化流程,详细了解有利于后续深入的了解spring其他实现机制。

参考资料:

https://github.com/DocsHome/spring-docs/blob/master/pages/core/IoC-container.mdhttps://blog.csdn.net/weixin_43738764/article/details/124966670https://blog.csdn.net/weixin_41605937/article/details/115004381https://www.jianshu.com/p/de879b493893

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

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

相关文章

【Java】Spring的创建和使用

Spring的创建和使用 Spring就是一个包含众多工具方法的IOC容器。既然是容器&#xff0c;那么就具备两个最主要的功能&#xff1a; 将对象存储到容器中从容器中将对象取出来 在Java语言当中对象也叫作Bean。 1. 创建Spring项目 创建一个普通maven项目添加Spring框架支持(spri…

Kotlin-面向对象

本片博客主要写创建对象&#xff0c;创建接口&#xff0c;创建抽象类&#xff0c;data关键字的作用 创建对象 如何声明一个对象&#xff0c;使用class关键字 格式为&#xff1a; class 对象名字(对象属性名&#xff1a;属性类型…)&#xff5b;&#xff5d; 如果对象没有函数…

python自学之《21天学通Python》(12)——第15章 线程和进程

现代操作系统大多都是多任务的&#xff0c;可以同时执行多个程序。进程是应用程序正在执行的实体&#xff0c;当程序执行时&#xff0c;也就创建了一个主线程。进程在创建和执行时需要一定的资源&#xff0c;比如内存、文件、I/O设备等。大多现代操作系统中支持多线程和进程。线…

JAVA服务端实现页面截屏(附代码)

JAVA服务端实现页面截屏适配需求方案一、使用JxBrowser使用步骤&#xff1a;方案二、JavaFX WebView使用步骤&#xff1a;方案三、Headless Chrome使用步骤&#xff1a;综上方案对比记录我的一个失败方案参考适配需求 有正确完整的地址url&#xff1b;通过浏览器能打开该url对…

Redis缓存一致性问题(缓存更新策略)

Redis缓存的一致性1. 缓存1.1 缓存的作用&#xff1a;1.2 缓存的成本&#xff1a;2. 缓存模型3. 缓存一致性问题3.1 引入3.2 解决(1) 先更新数据库&#xff0c;再手动删除缓存(2) 使用事务保证原子性(3) 以Redis中的TTL为兜底3.3 案例&#xff1a;商铺信息查询和更新(1) 查询商…

5.12 BGP选路原则综合实验

配置BGP的选路原则 1. 实验目的 熟悉BGP的选路的应用场景掌握BGP的选路的配置方法2. 实验拓扑 实验拓扑如图5-11所示: 图5-11:配置BGP的选路原则 3. 实验步骤 (1)配置IP地址 R1的配置

Spring中自定义Session管理,Spring Session源码解析

系列文章&#xff1a;Spring Boot学习大纲&#xff0c;可以留言自己想了解的技术点 目录 系列文章&#xff1a;Spring Boot学习大纲&#xff0c;可以留言自己想了解的技术点 1、session是什么&#xff1f; 1>session在哪里&#xff1f; 2>服务器怎么知道每次说话的是…

Python + Selenium,分分钟搭建 Web 自动化测试框架!

在程序员的世界中&#xff0c;一切重复性的工作&#xff0c;都应该通过程序自动执行。「自动化测试」就是一个最好的例子。 随着互联网应用开发周期越来越短&#xff0c;迭代速度越来越快&#xff0c;只会点点点&#xff0c;不懂开发的手工测试&#xff0c;已经无法满足如今的…

【Datawhale图机器学习】DeepWalk和Node2Vec

DeepWalk&#xff1a;用于图节点嵌入的在线机器学习算法 论文介绍 DeepWalk是基于随机游走的图节点嵌入算法。首次将深度学习和自然语言处理思想用于图机器学习&#xff0c;将随机游走序列与句子类比&#xff0c;节点与单词类比&#xff0c;构建Word2Vec的Skip-Gram无监督&am…

了解Axios及其运用方式

Axios简介 axios框架全称&#xff08;ajax – I/O – system&#xff09;&#xff1a; 基于promise用于浏览器和node.js的http客户端&#xff0c;因此可以使用Promise API 一、axios是干啥的 说到axios我们就不得不说下Ajax。在旧浏览器页面在向服务器请求数据时&#xff0c;…

计算机网络基础知识

目录 通信基础 前言 广播域与冲突域 计算机之间的连接方式 网线直连&#xff08;交叉线&#xff09; 同轴电缆 集线器 网桥 前言 举例&#xff08;计算机6向计算机7相互通信&#xff09; 交换机 交换机原理 路由器 路由器与其他设备区别&#xff1a; 注意&#…

Docker之路(3.docker底层原理、和虚拟机VM对比区别)

1.docker run 流程图 2. docker 底层原理 2.1 docker 是怎么工作的&#xff1f; Docker 是一个 Client-Server 结构的系统&#xff0c;Docker的守护进程运行在主机上&#xff0c; 通过Socket从客户端访问&#xff01; DockerServer接收到Docker-Client的指令&#xff0c;就会执…

【历史上的今天】2 月 22 日:Red Hat Enterprise Linux 问世;BASIC 语言作者出生;计算机协会创始人诞生

整理 | 王启隆 透过「历史上的今天」&#xff0c;从过去看未来&#xff0c;从现在亦可以改变未来。 今天是 2023 年 2 月 22 日&#xff0c;在 1857 年的今天&#xff0c;德国物理学家海因里希赫兹&#xff08;Heinrich Hertz&#xff09;出生。赫兹于 1887 年首先用实验证实了…

Mysql数据备份

一.数据备份的意义&#xff08;1&#xff09;保护数据的安全&#xff1b;&#xff08;2&#xff09;在出现意外的时候&#xff08;硬盘的损坏&#xff0c;断电&#xff0c;黑客的攻击&#xff09;&#xff0c;以便数据的恢复&#xff1b;&#xff08;3&#xff09;导出生产的数…

【音频处理和分析工具】上海道宁与NUGEN Audio助力您更轻松地提供高质量、合规的音频

NUGEN Audio的产品 可在任何情况下提供 先进的保真度和 不受限制的创造力 提供直接和直观的声音处理方式 NUGEN工具可以更轻松地 提供高质量、合规的音频 同时节省时间 降低成本并保留创作过程 开发商介绍 NUGEN Audio是后期制作、音乐和广播领域的知名品牌&#xff0c…

【Mysql】 锁

【Mysql】 锁 文章目录【Mysql】 锁1. 锁1.1 概述1.2 全局锁1.2.1 介绍1.2.2 语法1.2.2.1 加全局锁1.2.2.2 数据备份1.2.2.3 释放锁1.2.3 特点1.3 表级锁1.3.1 介绍1.3.2 表锁1.3.3 元数据锁1.3.4 意向锁1.4 行级锁1.4.1 介绍1.4.2 行锁1.4.3 间隙锁&临键锁1. 锁 1.1 概述…

一起学习用Verilog在FPGA上实现CNN----(八)integrationFC设计

1 integrationFC设计 LeNet-5网络结构全连接部分如图所示&#xff0c;该部分有2个全连接层&#xff0c;1个TanH激活层&#xff0c;1个SoftMax激活层&#xff1a; 图片来自附带的技术文档《Hardware Documentation》 integrationFC部分原理图&#xff0c;如图所示&#xff0c;…

python基于flask共享单车系统vue

可定制框架:ssm/Springboot/vue/python/PHP/小程序/安卓均可开发 目录 1 绪论 1 1.1课题背景 1 1.2课题研究现状 1 1.3初步设计方法与实施方案 2 1.4本文研究内容 2 2 系统开发环境 4 2. 3 系统分析 6 3.1系统可行性分析 6 3.1.1经济可行性 6 3.1.2技术可行性 6 3.1.3运行可行…

应用层协议

目录 应用层常见协议 DNS协议 前言 域名结构 DNS服务器分类 DNS的工作原理 DNS工作原理实例 DNS记录 DHCP协议 静态IP与动态IP DHCP协议好处 DHCP分配IP地址的4阶段 电子邮件 邮件的过程 电子邮件发送过程 pop协议特点 IMAP协议的特点 FTP协议 前言 FTP数据…

操作系统-初次理解

目录 1. 冯诺依曼体系 2. 操作系统 2.1 概念 2.2 解释 2.3 为什么管理 1. 冯诺依曼体系 我相信大家在学习计算机语言时一定听过这个体系结构的&#xff0c;那么这个结构到底是什么呢&#xff1f;上图&#xff1a; 该图是我对冯诺依曼体系结构简单构造&#xff0c;真实情况更…