springboot源码02-springboot启动主要步骤总结

news2024/11/22 10:27:34

文章目录

  • 【README】
  • 【1】springboot应用启动主要步骤
    • 【1.1】springboot应用启动主要步骤总结
  • 【2】springboot应用启动先后发布事件
    • 【2.1】springboot启动先后发布事件代码实践
      • 【2.1.1】自定义监听器
      • 【2.1.2】自定义SpringApplicationRunListener
      • 【2.1.3】springboot运行日志
  • 【3】补充:springboot自带的spring.factories

【README】

1)本文总结了springboot应用启动主要步骤;

2)springboot应用启动详细分析,参见: springboot应用启动过程源码分析

3)本文使用的springboot版本为3.3.5;



【1】springboot应用启动主要步骤

springboot启动主要步骤概述:

  • step1)new SpringApplication(primarySources): 实例化初始化器与监听器;

    • 1.1 数据源=META-INF/spring.factories ,通过反射实例化;
    • 1.2 初始化器包括 BootstrapRegistryInitializer实现类,ApplicationContextInitializer实现类,监听器包括ApplicationListener实现类;
  • step2)createBootstrapContext():创建默认启动容器,并使用 BootstrapRegistryInitializer 对其初始化;

    • 2.1 类型=DefaultBootstrapContext,
  • step3)SpringApplicationRunListeners listeners = getRunListeners(args): 实例化spring应用运行监听器

    • 3.1 数据源=META-INF/spring.factories , 通过反射实例化;
    • 3.2 类型=SpringApplicationRunListeners, 初始时只有1个: EventPublishingRunListener
  • stpe4)listeners.starting(bootstrapContext, this.mainApplicationClass):【发布事件:事件名=应用开始启动,事件类型=ApplicationStartingEvent

    • 4.1 调用SpringApplicationRunListeners-starting()方法;订阅者是ApplicationListener监听器;
  • step5)ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, …): 实例化并初始化环境Environment

  • 5.1 创建环境实例,类型=ApplicationServletEnvironment

  • 5.2 配置环境,包括配置属性,配置profiles

  • 5.3 listeners.environmentPrepared(bootstrapContext, environment); 【发布事件: 事件名=环境初始化完成, 事件类型=ApplicationEnvironmentPreparedEvent

  • 5.4 绑定环境实例到SpringApplication

  • 5.5 补充:【发布事件: 事件名=环境初始化完成,事件类型=ApplicationEnvironmentPreparedEvent

  • 5.5.1 订阅者是 ApplicationListener 监听器;其中有1个监听器=EnvironmentPostProcessorApplicationListener,接收到环境初始化完成事件后会实例化EnvironmentPostProcessor的实现类(数据源为spring.factories);

  • 5.5.2 并调用这些环境PostProcessor的postProcessEnvironment()方法;

  • 5.5.3 其中一个EnvironmentPostProcessor是 SystemEnvironmentPropertySourceEnvironmentPostProcessor ,用于做属性变量替换;

  • step6)context = createApplicationContext():创建spring容器;

    • 6.1 类型=AnnotationConfigServletWebServerApplicationContext
  • step7) prepareContext(bootstrapContext, context, environment, listeners, …): 初始化容器;

    • 7.1 装配environment到context

    • 7.2 postProcessApplicationContext(context):后置处理应用容器,包括注册BeanName生成器,设置资源加载器(classpath资源),设置类加载器,设置转换服务;

    • 7.3 使用初始化器初始化context,初始化器类型=ApplicationContextInitializer,数据源=META-INF/spring.factories,参见step1;

    • 7.4 listeners.contextPrepared(context); 【发布事件: 事件名=容器初始化完成,事件类型=ApplicationContextInitializedEvent

    • 7.5 【发布事件:事件名=启动容器关闭,事件类=BootstrapContextClosedEvent

    • 7.6 设置BeanFactory允许循环依赖,允许BeanDefinition重写;

    • 7.7 添加PropertySourceOrderingBeanFactoryPostProcessor

    • 7.8 获取资源列表,并加载BeanDefinition到容器,包括注解类,Resource文件,package资源;

    • 7.9 把 ApplicationListener 监听器添加到容器,监听器列表参见step1;

    • 7.10 【发布事件: 事件名=应用初始化完成,事件类型=ApplicationPreparedEvent

  • step8) refreshContext(context): 刷新容器

    • 8.1 shutdownHook.registerApplicationContext(context): 注册容器关闭钩子; 注册ApplicationContextClosedListener监听器,监听ContextClosedEvent

    • 8.2 refresh(context): 刷新容器;大致思想是根据BeanDefinition实例化bean;

      • 参见 spring容器启动源码解读 章节【3.1】

      • bean实例化主要步骤总结【非常重要,常见spring面试题】

        步骤1) 实例化bean; (instantiateBean方法, 使用BeanDefinition+反射技术,工具方法-BeanUtils.instantiateClass)
        步骤2) 填充bean属性;(populateBean方法,如Autowire自动装配依赖,属性变量替换);
        步骤3) 初始化bean; (initializeBean方法)
            调用Aware装配方法; (如BeanNameAware,BeanClassLoaderAware, BeanFactoryAware)
            用BeanPostProcessor的初始化前置方法; (postProcessBeforeInitialization方法)
            调用初始化方法() ; (调用InitializingBean#afterPropertiesSet方法,调用配置的init方法)
            调用BeanPostProcessor的初始化后置方法; (postProcessAfterInitialization方法)
        步骤4)注册可销毁bean;
            调用registerDisposableBeanIfNecessary(), 可销毁bean=DisposableBean ;
        步骤5) 调用SmartInitializingSingleton敏捷初始化单例的afterSingletonsInstantiated()
            若bean实现SmartInitializingSingleton接口;
        
  • step9) afterRefresh(context, applicationArguments): 默认空,子类可以实现

  • step10) listeners.started(context, startup.timeTakenToStarted()):

    • 10.1 【发布事件: 事件名=应用启动完成, 事件类型=ApplicationStartedEvent
    • 10.2 【发布事件: 事件名=可用性变更, 事件类型=AvailabilityChangeEvent,可用性状态=LivenessState.CORRECT 即存活状态正确
  • step11)callRunners(context, applicationArguments): 调用运行器Bean;类型包括ApplicationRunner,CommandLineRunner

  • stpe12) listeners.ready(context, startup.ready())

    • 12.1 【发布事件: 事件名=应用就绪, 事件类型=ApplicationReadyEvent
    • 12.2 【发布事件: 事件名=可用性变更, 事件类型=AvailabilityChangeEvent,可用性状态=ReadinessState.ACCEPTING_TRAFFIC 即就绪状态可以接收流量


【1.1】springboot应用启动主要步骤总结

在这里插入图片描述



【2】springboot应用启动先后发布事件

1)springboot应用启动时先后发布的事件如下:

  • 【发布事件:事件名=应用开始启动,事件类型=ApplicationStartingEvent 】
  • 【发布事件: 事件名=环境初始化完成, 事件类型=ApplicationEnvironmentPreparedEvent 】
  • 【发布事件: 事件名=容器初始化完成,事件类型=ApplicationContextInitializedEvent 】
  • 【发布事件:事件名=启动容器关闭,事件类=BootstrapContextClosedEvent 】
  • 【发布事件: 事件名=应用初始化完成,事件类型=ApplicationPreparedEvent 】
  • 【发布事件: 事件名=应用启动完成, 事件类型=ApplicationStartedEvent 】
  • 【发布事件: 事件名=可用性变更, 事件类型=AvailabilityChangeEvent,可用性状态=LivenessState.CORRECT 即存活状态正确 】
  • 【发布事件: 事件名=应用就绪, 事件类型=ApplicationReadyEvent 】
  • 【发布事件: 事件名=可用性变更, 事件类型=AvailabilityChangeEvent,可用性状态=ReadinessState.ACCEPTING_TRAFFIC 即就绪状态可以接收流量 】

2)发布事件时间线总结

  • 先实例化及初始化环境;
  • 然后实例化及初始化容器;
  • 接着实例化及初始化应用;
    • 应用初始化完成事件;
    • 根据BeanDefinition实例化Bean 【非常重要】 ; 思考题: BeanDefinition从哪里来?
    • 应用启动完成事件;
  • 最后应用就绪,发布 ACCEPTING_TRAFFIC(=接收流量) 可用性变更事件;

3)为什么我们这么关注事件:因为springboot脚手架通过事件通知订阅者执行自定义业务逻辑,达到功能扩展的目的(如初始化或替换环境变量)


【2.1】springboot启动先后发布事件代码实践

【FirstSpringbootApplication】springboot启动入口

@SpringBootApplication
public class FirstSpringbootApplication {

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


【2.1.1】自定义监听器

自定义监听器并添加到META-INF/spring.factories,以便springboot应用启动时读取并实例化监听器

每个监听器监听(订阅)不同事件; 当发布者发布事件时,监听器接收事件;

// 监听 ApplicationContextInitializedEvent
public class TomApplicationContextInitializedEventListener implements ApplicationListener<ApplicationContextInitializedEvent> {
    @Override
    public void onApplicationEvent(ApplicationContextInitializedEvent event) {
        System.out.println("事件名=容器初始化完成,事件类型=ApplicationContextInitializedEvent");
    }

    @Override
    public boolean supportsAsyncExecution() {
        return false;
    }
}

// 监听ApplicationEnvironmentPreparedEvent 
public class TomApplicationEnvironmentPreparedEventListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
    @Override
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
        System.out.println("事件名=环境初始化完成, 事件类型=ApplicationEnvironmentPreparedEvent");
    }

    @Override
    public boolean supportsAsyncExecution() {
        return false;
    }
}

// 监听ApplicationPreparedEvent 
public class TomApplicationPreparedEventListener implements ApplicationListener<ApplicationPreparedEvent> {
    @Override
    public void onApplicationEvent(ApplicationPreparedEvent event) {
        System.out.println("事件名=应用初始化完成,事件类型=ApplicationPreparedEvent");
    }

    @Override
    public boolean supportsAsyncExecution() {
        return false;
    }
}

// 监听 ApplicationReadyEvent
public class TomApplicationReadyEventListener implements ApplicationListener<ApplicationReadyEvent> {
    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        System.out.println("事件名=容器就绪, 事件类型=ApplicationReadyEvent");
    }

    @Override
    public boolean supportsAsyncExecution() {
        return false;
    }
}

// 监听 ApplicationStartedEvent 
public class TomApplicationStartedEventListener implements ApplicationListener<ApplicationStartedEvent> {
    @Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        System.out.println("事件名=容器启动完成, 事件类型=ApplicationStartedEvent");
    }

    @Override
    public boolean supportsAsyncExecution() {
        return false;
    }
}

// 监听 ApplicationStartingEvent
public class TomApplicationStartingEventListener implements ApplicationListener<ApplicationStartingEvent> {
    @Override
    public void onApplicationEvent(ApplicationStartingEvent event) {
        System.out.println("事件名=应用开始启动,事件类型=ApplicationStartingEvent");
    }

    @Override
    public boolean supportsAsyncExecution() {
        return false;
    }
}

// 监听 AvailabilityChangeEvent
public class TomAvailabilityChangeEventListener implements ApplicationListener<AvailabilityChangeEvent> {
    @Override
    public void onApplicationEvent(AvailabilityChangeEvent event) {
        System.out.println("事件名=可用性变更, 事件类型=AvailabilityChangeEvent, event.getState()=" + event.getState());
    }

    @Override
    public boolean supportsAsyncExecution() {
        return false;
    }
}

// 监听 BootstrapContextClosedEvent
public class TomBootstrapContextClosedEventListener implements ApplicationListener<BootstrapContextClosedEvent> {
    @Override
    public void onApplicationEvent(BootstrapContextClosedEvent event) {
        System.out.println("事件名=启动容器关闭,事件类=BootstrapContextClosedEvent");
    }

    @Override
    public boolean supportsAsyncExecution() {
        return false;
    }
}

【spring.factories】

org.springframework.context.ApplicationListener=\
com.tom.springnote.chapter03.listener.TomApplicationContextInitializedEventListener,\
com.tom.springnote.chapter03.listener.TomApplicationEnvironmentPreparedEventListener,\
com.tom.springnote.chapter03.listener.TomApplicationPreparedEventListener,\
com.tom.springnote.chapter03.listener.TomApplicationReadyEventListener,\
com.tom.springnote.chapter03.listener.TomApplicationStartedEventListener,\
com.tom.springnote.chapter03.listener.TomApplicationStartingEventListener,\
com.tom.springnote.chapter03.listener.TomAvailabilityChangeEventListener,\
com.tom.springnote.chapter03.listener.TomBootstrapContextClosedEventListener


【2.1.2】自定义SpringApplicationRunListener

1)一般不自定义SpringApplicationRunListener,因为监听范围太大,本文只做测试用;

【TomSpringAppRunListener01】

public class TomSpringAppRunListener01 implements SpringApplicationRunListener {

    @Override
    public void starting(ConfigurableBootstrapContext bootstrapContext) {
        System.out.println("TomSpringAppRunListener01 starting");
    }

    @Override
    public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
        System.out.println("TomSpringAppRunListener01 environmentPrepared");
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        System.out.println("TomSpringAppRunListener01 contextPrepared");
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        System.out.println("TomSpringAppRunListener01 contextLoaded");
    }

    @Override
    public void started(ConfigurableApplicationContext context, Duration timeTaken) {
        System.out.println("TomSpringAppRunListener01 started");
    }

    @Override
    public void ready(ConfigurableApplicationContext context, Duration timeTaken) {
        System.out.println("TomSpringAppRunListener01 ready");
    }
}

【spring.factories】配置TomSpringAppRunListener01

# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
com.tom.springnote.chapter03.springapprunlistener.TomSpringAppRunListener01


【2.1.3】springboot运行日志

1)springboot应用启动时的事件发布日志

事件名=应用开始启动,事件类型=ApplicationStartingEvent
TomSpringAppRunListener01 starting

--------------------
事件名=环境初始化完成, 事件类型=ApplicationEnvironmentPreparedEvent
TomSpringAppRunListener01 environmentPrepared

--------------------
事件名=容器初始化完成,事件类型=ApplicationContextInitializedEvent
TomSpringAppRunListener01 contextPrepared

--------------------
事件名=应用初始化完成,事件类型=ApplicationPreparedEvent
TomSpringAppRunListener01 contextLoaded

--------------------
事件名=应用启动完成, 事件类型=ApplicationStartedEvent
TomSpringAppRunListener01 started

--------------------
事件名=可用性变更, 事件类型=AvailabilityChangeEvent, event.getState()=CORRECT

--------------------
事件名=应用就绪, 事件类型=ApplicationReadyEvent
TomSpringAppRunListener01 ready

--------------------
事件名=可用性变更, 事件类型=AvailabilityChangeEvent, event.getState()=ACCEPTING_TRAFFIC

补充:ACCEPTING_TRAFFIC 表示接收流量

事件名=可用性变更, 事件类型=AvailabilityChangeEvent, event.getState()=REFUSING_TRAFFIC

补充:REFUSING_TRAFFIC表示拒绝流量



【3】补充:springboot自带的spring.factories

1)spring.factories 文件在 spring-boot jar包下;文件中的内容配置了bean的全限定类型,用于springboot自动配置; 【当然其他jar包也有,本文不展开】

在这里插入图片描述

2)spring.factories主要内容如下;

# Logging Systems  【日志系统】
org.springframework.boot.logging.LoggingSystemFactory=\
org.springframework.boot.logging.logback.LogbackLoggingSystem.Factory,\
org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.Factory,\
org.springframework.boot.logging.java.JavaLoggingSystem.Factory

# PropertySource Loaders  【属性源加载器】
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader

# ConfigData Location Resolvers 【配置数据位置解析器】
org.springframework.boot.context.config.ConfigDataLocationResolver=\
org.springframework.boot.context.config.ConfigTreeConfigDataLocationResolver,\
org.springframework.boot.context.config.StandardConfigDataLocationResolver

# ConfigData Loaders  【配置数据加载器】
org.springframework.boot.context.config.ConfigDataLoader=\
org.springframework.boot.context.config.ConfigTreeConfigDataLoader,\
org.springframework.boot.context.config.StandardConfigDataLoader

# Application Context Factories 【应用容器工厂】
org.springframework.boot.ApplicationContextFactory=\
org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContextFactory,\
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContextFactory

# Run Listeners  【运行时监听器,用于发布springboot应用的启动事件】
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener

# Error Reporters 
org.springframework.boot.SpringBootExceptionReporter=\
org.springframework.boot.diagnostics.FailureAnalyzers

# Application Context Initializers 【容器初始化器】
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

# Application Listeners  【应用监听器,用于监听springboot启动事件】
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.env.EnvironmentPostProcessorApplicationListener

# Environment Post Processors   【环境后置处理器, 用于装配环境变量】
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor,\
org.springframework.boot.env.RandomValuePropertySourceEnvironmentPostProcessor,\
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor,\
org.springframework.boot.reactor.ReactorEnvironmentPostProcessor

# Failure Analyzers  【略过】
# Failure Analysis Reporters 【略过】

# Database Initializer Detectors  【初始化器检测器】
org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector=\
org.springframework.boot.flyway.FlywayDatabaseInitializerDetector,\
org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializerDetector,\
org.springframework.boot.liquibase.LiquibaseDatabaseInitializerDetector,\
org.springframework.boot.orm.jpa.JpaDatabaseInitializerDetector,\
org.springframework.boot.r2dbc.init.R2dbcScriptDatabaseInitializerDetector

# Depends On Database Initialization Detectors  【初始化器检测器】
org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector=\
org.springframework.boot.sql.init.dependency.AnnotationDependsOnDatabaseInitializationDetector,\
org.springframework.boot.jdbc.SpringJdbcDependsOnDatabaseInitializationDetector,\
org.springframework.boot.jooq.JooqDependsOnDatabaseInitializationDetector,\
org.springframework.boot.orm.jpa.JpaDependsOnDatabaseInitializationDetector

# Resource Locator Protocol Resolvers  【资源定位协议解析器】 
org.springframework.core.io.ProtocolResolver=\
org.springframework.boot.io.Base64ProtocolResolver

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

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

相关文章

数据结构——小小二叉树第二幕(二叉树链式结构的实现以及二叉树的遍历)超详细!!!

文章目录 前言一、实现链式结构二叉树1.1 前中后序遍历1.1.1 遍历规则 1.2 二叉树的结点个数以及高度等 总结 前言 上一篇我们初步认识了树的结构以及概念&#xff0c;同时也学习到了二叉树的顺序结构&#xff08;堆&#xff09;的实现&#xff0c;以及堆的初步应用。 时隔几日…

服务器端渲染 (SSR) 与客户端渲染 (CSR)

嘿程序员&#xff01;我们都知道&#xff0c;新时代的 Javascript 已经彻底改变了现代网站的结构和用户体验。如今&#xff0c;网站的构建更像是一个应用程序&#xff0c;伪装成一个能够发送电子邮件、通知、聊天、购物、支付等的网站。今天的网站是如此先进、互动&#xff0c;…

【spring】spring单例模式与锁对象作用域的分析

前言&#xff1a;spring默认是单例模式&#xff0c;这句话大家应该都不陌生&#xff1b;因为绝大多数都是使用单例模式&#xff0c;避免了某些问题&#xff0c;可能导致对某些场景缺乏思考。本文通过结合lock锁将单例模式、静态变量、锁对象等知识点串联起来。 文章目录 synchr…

解析与修复vcruntime140_1.dll问题,总结四种vcruntime140_1.dll解决方法

在使用Windows系统的过程中&#xff0c;不少用户可能会遇到与vcruntime140_1.dll相关的问题。这个看似神秘的文件&#xff0c;其实在很多软件的运行中扮演着至关重要的角色。今天的这篇文章将教大家四种vcruntime140_1.dll解决方法。 一、vcruntime140_1.dll文件分析 &#xf…

django基于django的民族服饰数据分析系统的设计与实现

摘 要 随着网络科技的发展&#xff0c;利用大数据分析对民族服饰进行管理已势在必行&#xff1b;该平台将帮助企业更好地理解服饰市场的趋势&#xff0c;优化服装款式&#xff0c;提高服装的质量。 本文讲述了基于python语言开发&#xff0c;后台数据库选择MySQL进行数据的存储…

如何使用GPT API 自定义 自己的 RAG

要使用 GPT 的 API 实现自己的 RAG&#xff08;Retrieval-Augmented Generation&#xff09; 系统&#xff0c;可以结合检索工具和 GPT 模型&#xff0c;将外部知识库中的信息与生成模型结合起来&#xff0c;完成准确、高效的任务。以下是具体步骤和实现方法&#xff1a; 系统架…

对subprocess启动的子进程使用VSCode python debugger

文章目录 1 情况概要&#xff08;和文件结构&#xff09;2 具体设置和启动步骤2.1 具体配置Step 1 针对attach debugger到子进程Step 2 针对子进程的暂停(可选) Step 3 判断哪个进程id是需要的子进程 2.2 启动步骤和过程 3 其他问题解决3.13.2 ptrace: Operation not permitted…

cocos creator 3.8 一些简单的操作技巧,材质的创建 1

这是一个飞机的3D模型与贴图 导入到cocos中&#xff0c;法线模型文件中已经包含了mesh、material、prefab&#xff0c;也就是模型、材质与预制。界面上创建一个空节点Plane&#xff0c;将模型直接拖入到Plane下。新建材质如图下 Effect属性选择builtin-unlit&#xff0c;不需…

基于web的音乐网站(Java+SpringBoot+Mysql)

目录 1系统概述 1.1 研究背景 1.2研究目的 1.3系统设计思想 2相关技术 2.1 MYSQL数据库 2.2 B/S结构 2.3 Spring Boot框架简介 3系统分析 3.1可行性分析 3.1.1技术可行性 3.1.2经济可行性 3.1.3操作可行性 3.2系统性能分析 3.2.1 系统安全性 3.2.2 数据完整性 …

Web中间件漏洞总结——IIS篇

0x01 前言 渗透过程中会遇到各种中间件&#xff0c;某些中间件版本存在远程执行、任意文件上传等漏洞。本文对IIS相关漏洞进行整理&#xff0c;方便我们在渗透过程中快速查阅IIS漏洞。文章粗略浅显&#xff0c;适合刚入行的新手观看。 0x02 目录 IIS6.0 PUT漏洞IIS6.0 远程代…

关于中断向量表中没有EXTIx_IRQHandler的问题

如果你在中断向量表查找中断向量服务函数时&#xff0c;没有查找到EXTI7_IRQHandler等&#xff0c;是因为中断向量中根本就没有这个函数。 STM32 的中断向量表通常由启动文件&#xff08;如 startup_stm32f1xx.s&#xff09;定义。在该文件中&#xff0c;所有的中断服务例程&a…

idea启动服务报错Application run failed

现象是这样&#xff0c;在宝兰德部署报错&#xff1a; NoClassDefFoundError: org/apache/tomcat/util/codec/binary/Base64 本地启动报错&#xff1a;Application run failed:Failed to parse configuration class [***.WebApplication]; nested exception is java.lang.Illeg…

Easyexcel(4-模板文件)

相关文章链接 Easyexcel&#xff08;1-注解使用&#xff09;Easyexcel&#xff08;2-文件读取&#xff09;Easyexcel&#xff08;3-文件导出&#xff09;Easyexcel&#xff08;4-模板文件&#xff09; 文件导出 获取 resources 目录下的文件&#xff0c;使用 withTemplate 获…

神经网络问题之:梯度不稳定

梯度不稳定是深度学习中&#xff0c;特别是在训练深度神经网络时常见的一个问题&#xff0c;其本质涉及多个方面。 一、根本原因 梯度不稳定问题的根本原因在于深度神经网络的结构和训练过程中的一些固有特性。随着网络层数的增加&#xff0c;梯度在反向传播过程中会逐层累积变…

动态规划子数组系列一>等差数列划分

题目&#xff1a; 解析&#xff1a; 代码&#xff1a; public int numberOfArithmeticSlices(int[] nums) {int n nums.length;int[] dp new int[n];int ret 0;for(int i 2; i < n; i){dp[i] nums[i] - nums[i-1] nums[i-1] - nums[i-2] ? dp[i-1]1 : 0;ret dp[i…

RedHat系统配置静态IP

1、执行nmtui命令进入字符配置界面如下图所示 2、选择编辑连接进入 3、选择编辑进入后&#xff0c;将IPv4设置为手动模式后&#xff0c;选择显示后进行ip地址、网关、DNS的配置&#xff0c;配置完成后选择确定退出编辑 4、进入主界面后选择启用连接进入后&#xff0c;选择启用&…

batchnorm与layernorn的区别

1 原理 简单总结&#xff1a; batchnorn 和layernorm是在不同维度上对特征进行归一化处理。 batchnorm在batch这一维度上&#xff0c; 对一个batch内部所有样本&#xff0c; 在同一个特征通道上进行归一化。 举个例子&#xff0c; 假设输入的特征图尺寸为16x224x224x256&…

【Redis】持久化机制RDB与AOF

一、RDB RDB模式是就是将内存中的数据存储到磁盘中&#xff0c;等到连接断开的时候会进行持久化操作。但是如果服务器宕机&#xff0c;会导致这个持久化机制不会执行&#xff0c;但是内存中的文件会直接丢失。所以可以设置一个触发机制&#xff0c;save 60 1000 就是代表60秒 执…

JSON,事件绑定

文章目录 JSON事件绑定输入框input和div的内容返回获取dom元素数组还是单个对象for循环为什么要写const那一行&#xff0c;直接写 hobbys[index].checked true;可以吗const不是常量吗&#xff0c;为什么用const声明的element的属性值可以改变&#xff1f; 黑马学习笔记 JSON 定…

Kotlin Multiplatform 未来将采用基于 JetBrains Fleet 定制的独立 IDE

近期 Jetbrains 可以说是动作不断&#xff0c;我们刚介绍了 IntelliJ IDEA 2024.3 K2 模式发布了稳定版支持 &#xff0c;而在官方最近刚调整过的 Kotlin Multiplatform Roadmap 优先关键事项里&#xff0c;可以看到其中就包含了「独立的 Kotlin Multiplatform IDE&#xff0c;…