欢迎来到皮皮网网首页

【精品汽车源码】【yarn router 源码】【ugui修改源码】spring源码启动

来源:ktv招聘源码 时间:2024-11-25 05:00:14

1.springԴ?源码?????
2.Spring源码Autowired注入流程
3.SpringBoot源码学习——SpringBoot自动装配源码解析+Spring如何处理配置类的
4.SpringBoot源码 | refreshContext方法解析
5.Spring源码 1.源码的下载与编译(by Gradle)
6.springboot如何启动内置tomcat?(源码详解)

spring源码启动

springԴ??????

       源码版本

       作者使用的是Spring Boot的2.4.0版本。不同版本的启动Spring Boot可能存在差异,建议读者与作者保持一致,源码以确保源码的启动一致性。

       从哪入手

       Spring Boot源码的源码研究起点是主启动类,即标注着`@SpringBootApplication`注解并且包含`main()`方法的启动精品汽车源码类。这是源码Spring Boot启动的核心。

       源码如何切分

       SpringApplication中的启动静态`run()`方法是一个复杂的流程,它分为两步:创建`SpringApplication`对象和执行`run()`方法。源码接下来将分别介绍这两部分。启动

       如何创建`SpringApplication`

       创建`SpringApplication`的源码过程本质上是一个对象的生成,通过调试追踪,启动最终调用的源码构造方法如图所示。创建过程主要涉及三个阶段,启动我们将逐一进行深入。源码

       设置应用类型

       创建过程中的重要步骤是确定应用类型,这将直接影响项目的性质,如Web应用或非Web应用。应用类型由WebApplicationType枚举类决定,加载特定类(如DispatcherServlet)来判断。

       设置初始化器

       初始化器(ApplicationContextInitializer)用于在IOC容器刷新之前进行初始化操作,例如ServletContextApplicationContextInitializer。获取初始化器的方式是从SpringApplication中的方法调用开始的,最终通过`#SpringFactoriesLoader.loadSpringFactories()`方法从类路径加载。

       设置监听器

       监听器(ApplicationListener)负责监听特定的事件(如IOC容器刷新或关闭)。在Spring Boot中,使用SpringApplicationEvent事件来扩展监听器概念,主要在启动过程中触发。获取监听器的方式与初始化器相同,从spring.factories文件中加载。

       总结

       SpringApplication的构建为`run()`方法的执行铺平了道路,关键步骤包括设置应用类型、初始化器和监听器。注意,初始化器和监听器需要在spring.factories文件中声明,才能在构建过程中加载,此时IOC容器尚未创建,即使注入到容器中也不会生效。

       执行`run()`方法

       在构建结束后,到了启动的yarn router 源码阶段,`run()`方法将执行一系列操作,分为八个步骤进行详细解析。

       步骤1:获取并启动运行过程监听器

       SpringApplicationRunListener监听器用于监听应用程序的启动过程,通过调用方法从spring.factories文件中获取运行监听器实例,并执行特定事件的广播。

       步骤2:环境构建

       构建过程包括加载系统和自定义配置(如application.properties),并广播事件通知监听器。

       步骤3:创建IOC容器

       执行容器创建过程,根据应用类型选择容器类型,此步骤仅创建容器,未进行其他操作。

       步骤4:IOC容器的前置处理

       这一步是容器刷新前的准备工作,关键操作是将主启动类注入容器,为后续自动化配置奠定基础。

       步骤5:调用初始化器

       执行构建过程中设置的初始化器,加载自定义的初始化器实现。

       步骤6:加载启动类,注入容器

       将主启动类加载到IOC容器中,作为自动配置的入口。

       步骤7:两次事件广播

       这一步涉及两次事件广播,包括ApplicationContextInitializedEvent和ApplicationPreparedEvent。

       步骤8:刷新容器

       容器刷新由Spring框架完成,包括资源初始化、上下文广播器等。

       步骤9:IOC容器的后置处理

       这一步是容器刷新后的扩展操作,通常用于打印结束日志等。

       步骤:发出结束执行的事件

       使用EventPublishingRunListener广播ApplicationStartedEvent事件,允许在IOC容器中注入的监听器响应。

       步骤:执行Runners

       Spring Boot提供了两种Runner,即CommandLineRunner和ApplicationRunner,用于定制额外操作。

       总结

       Spring Boot启动流程相对简洁,通过八个步骤详细描述了从创建到执行的整个过程。理解run()方法的执行流程、事件、初始化器和监听器的执行时间点是关键。

Spring源码Autowired注入流程

       在Spring框架中,Autowired注解的注入流程是一个开发者常问的问题。本文将带你深入了解这一过程,ugui修改源码基于jdk1.8和spring5.2.8.RELEASE环境。

       首先,当Spring应用启动,通过SpringApplication的run方法调用refreshContext,进而执行refresh方法,初始化上下文容器。在这个过程中,非懒加载的bean实例化由finishBeanFactoryInitialization方法负责,特别是其内部的beanFactory.preInstantiateSingletons方法。

       在默认非单例bean的getBean方法中,会调用AbstractAutowireCapableBeanFactory的createBean方法,这个方法会处理包括@Autowired在内的各种注解。特别关注AutowiredAnnotationBeanPostProcessor,它在获取元数据后,会进入beanFactory.resolveDependency来处理可能的多个依赖问题。

       最后,DefaultListableBeanFactory的doResolveDependency方法通过反射机制,实现了属性注入。尽管这只是整个流程的概述,但深入源码可以帮助我们更好地理解Autowired的底层工作机制。

       虽然这只是一个基本的梳理,但希望能为理解Spring的Autowired注入提供一些帮助。写这篇文章我投入了一周的时间,尽管过程艰辛,但如果觉得有价值,请给予鼓励,如点赞、收藏或转发。期待您的宝贵意见,让我们共同进步!

SpringBoot源码学习——SpringBoot自动装配源码解析+Spring如何处理配置类的

       SpringBoot通过SPI机制,借助外部引用jar包中的META-INF/spring.factories文件,实现引入starter即可激活功能,简化手动配置bean,实现即开即用。

       启动SpringBoot服务,通常使用Main方法启动,其中@SpringBootApplication注解包含@SpringBootConfiguration、@EnableAutoConfiguration、游戏源码公式@ComponentScan,自动装配的核心。

       深入分析@SpringBootApplication,其实质是执行了@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三个注解的功能,简化了配置过程,强调了约定大于配置的思想。

       SpringBoot的自动装配原理着重于研究如何初始化ApplicationContext,Spring依赖于ApplicationContext实现其功能,SpringApplication#run方法为初始化ApplicationContext的入口。

       分析SpringApplication构造方法,SpringApplication.run(启动类.class, args) 实际调用的是该方法,其关键在于根据项目类型反射生成合适的ApplicationContext。

       选择AnnotationConfigServletWebServerApplicationContext,此上下文具备启动Servlet服务器和注册Servlet或过滤器类型bean的能力。

       准备刷新ApplicationContext,SpringBoot将主类注册到Spring容器中,以便@ConfigurationClassPostProcessor解析主类注解,发挥@Import、@ComponentScan的作用。

       刷新ApplicationContext过程包括一系列前置准备,如将主类信息封装成AnnotatedGenericBeanDefinition,解析注解并调用BeanDefinitionCustomizer自定义处理。

       解析配置类中的注解,通过BeanDefinitionRegistryPostProcessor和ConfigurationClassParser实现,筛选、排序候选者,并解析@Import注解实现自动装配。

       增强配置类,ConfigurationClassPostProcessor对full模式的配置进行增强,确保@Import正确处理,CGLIB用于增强原配置类,确保生命周期完整,避免真正执行@Bean方法逻辑。

       深入解析AutoConfigurationImportSelector实现自动装配,通过spring.boot.enableautoconfiguration设置开启状态,读取spring-autoconfigure-metadata.properties和META-INF/spring.factories文件,筛选并加载自动配置类。maxcms网源码

SpringBoot源码 | refreshContext方法解析

       本文主要解析SpringBoot启动流程中的`refreshContext`方法。在SpringBoot启动过程中,主要涉及两个阶段:初始化`SpringApplication`对象和`SpringApplication.run`方法执行的内容。`refreshContext`方法的执行,标志着启动流程的深入。

       `refreshContext`方法的主要功能是刷新容器,其源码揭示了这一过程的关键步骤。首先,方法通过调用`refresh`来实现底层`ApplicationContext`的刷新。`ApplicationContext`接口的抽象实现类`AbstractApplicationContext`,通过模板方法设计模式,要求具体子类实现抽象方法,以适应不同的配置存储需求。

       `refresh`方法执行了一系列操作,包括准备刷新上下文、调用上下文注册为bean的工厂处理器、初始化上下文的消息源、初始化特定上下文子类中的其他特殊bean、检查监听器bean并注册,以及发布相应的事件并销毁已经创建的单例及重置active标志。

       在`refresh`方法内部,`prepareRefresh`方法负责准备上下文以进行刷新,包括设置启动日期和活动标志,以及执行属性源的初始化。`obtainFreshBeanFactory`方法获取新的bean工厂,通过`refreshBeanFactory`方法进行配置,以及`getBeanFactory`方法返回当前上下文的内部bean工厂。

       `prepareBeanFactory`方法配置工厂标准的上下文特征,如上下文类加载器、后置处理器等。`postProcessBeanFactory`方法进一步处理bean工厂,根据WebApplicationType选择特定的操作,如添加后置处理器以及注册特定的web作用域。

       `invokeBeanFactoryPostProcessors`方法调用bean工厂的后置处理器,`registerBeanPostProcessors`方法实例化并注册所有后置处理器bean。`initMessageSource`方法初始化应用上下文消息源,而`initApplicationEventMulticaster`方法则为上下文初始化事件多播。

       `onRefresh`方法执行刷新操作,`createWebServer`方法创建web服务,`registerListeners`方法检查并注册监听器。`finishBeanFactoryInitialization`方法实例化所有剩余的单例bean,而`finishRefresh`方法发布事件,重置Spring核心中的公共内省缓存,标志着容器刷新的结束。

       `resetCommonCaches`方法重置Spring核心中的公共内省缓存,`contextRefresh.end`方法容器刷新结束,最终执行日志打印,完成启动流程。

       总的来说,`refreshContext`方法的执行流程清晰,通过丰富的源码注释,便于学习者深入理解SpringBoot启动机制。本文仅提供方法解析的概览,更多细节请参考原始源码。

Spring源码 1.源码的下载与编译(by Gradle)

       为了获得Spring源码并成功编译,我们首先需要下载源码。方法之一是使用Git clone命令,前提是我们已安装Git。但要注意,最新版本可能需要JDK ,若需使用JDK 8,推荐选择较旧版本。GitHub上,最新稳定版本为5.2..RELEASE,这是一个GA(General Availability)版本,表示正式发布的版本,适合在生产环境中使用。如果你使用的是JDK 8,建议选择分支版本。

       如果GitHub服务不可用或下载速度缓慢,可以考虑从其他资源库下载。例如,可以使用csdn提供的资源链接支持作者,或者直接从gitee下载源码。

       下载源码后,导入IDEA并选择Gradle工程。IDEA会自动加载,但可能遇到一些报错。如果报错提示“POM relocation to an other version number is not fully supported in Gradle”,需要将xml-apis的版本号更改为1.0.b2。这可以通过在项目的build.gradle文件中添加指定版本的代码来实现。

       加载并配置新模块后,可以通过新建测试类来进行验证。在build.gradle中添加配置,并在模块中新建文件,包括一个启动类、一个配置类和一个实体类。记得刷新Gradle,进行测试。

       测试结果应显示新建的实体类已被Spring容器加载。如果在测试中遇到问题,可以通过检查编译工具、编译器和项目结构来解决。确保使用本地Gradle路径、选择JDK 1.8版本,并在项目设置中选择正确的JDK版本。

springboot如何启动内置tomcat?(源码详解)

       SpringBoot项目启动时,无需依赖传统Tomcat,因为内部集成了Tomcat功能。本文将深入解析SpringBoot如何通过源码启动内置Tomcat。

       关键点在于`registerBeanPostProcessors`的`onRefresh`方法,它扩展了容器对象和bean实例化过程,确保单例和实例化完成。`initApplicationEventMuliticaster`则注册广播对象,与`applicationEvent`和`applicationListener`紧密相关。

       文章的核心内容集中在`onRefresh()`方法,其中`createWenServer()`是关键。当`servletContext`和`webServer`为空时,会创建并初始化相关的组件,如`servletWebServerFactory`、`servletContext`(Web请求上下文)、`webServer`(抽象的web容器封装)和`WebServer`实例。`getWebServer()`方法允许在Spring容器刷新后连接webServer。

       SpringBoot通过`TomcatServletWebServerFactory`获取webServer,该工厂负责创建和配置webServer,包括Tomcat组件的初始化,如`Connector`和`Context`的设置,以及与wrapper、engine、service和host等的关联。`new Connector`会根据传入的协议进行定制化配置。

       理解了这些扩展点,用户可以自定义配置,通过`ServerProperties`或自定义`tomcatConnectorCustomizers`和`tomcatProtocolHandlerCustomizers`来扩展Tomcat的连接器和协议处理器。这就是SpringBoot设计的巧妙之处。

       最后,SpringBoot的启动流程涉及逐层初始化和启动Tomcat的组件,如engine、context和wrapper,它们通过生命周期方法如`init`、`start`和`destroy`协同工作。启动过程本质上是一个链式调用,每个组件的初始化和启动都会触发下一层组件的逻辑。

Spring容器之refresh方法源码分析

       Spring容器的核心接口BeanFactory与ApplicationContext之间的关系是继承,ApplicationContext扩展了BeanFactory的功能,提供了初始化环境、参数、后处理器、事件处理以及单例bean初始化等更全面的服务,其中refresh方法是Spring应用启动的入口点,负责整个上下文的准备工作。

       让我们深入分析AbstractApplicationContext#refresh方法在启动过程中的具体操作:

准备刷新阶段: 包括系统属性和环境变量的检查和准备。

获取新的BeanFactory: 初始化并解析XML配置文件。

       customizeBeanFactory: 个性化BeanFactory设置,如覆盖定义、处理循环依赖等。

       loadBeanDefinitions: 通过解析XML文件,创建BeanDefinition对象并注入到容器中。

填充BeanFactory功能: 设置classLoader、表达式语言处理器,增强Aware接口处理,添加AspectJ支持和默认系统环境bean等。

激活BeanFactory后处理器: 分为BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor,分别进行BeanDefinition注册和BeanFactory增强。

注册BeanPostProcessors: 拦截Bean创建的后处理器,按优先级注册。

初始化其他组件: 包括MessageSource、ApplicationEventMulticaster和监听器。

初始化非惰性单例: 预先实例化这些对象。

刷新完成: 通知生命周期处理器并触发ContextRefreshedEvent。

       以上是refresh方法在Spring应用启动流程中的关键步骤。以上内容仅为个人理解,如需更多信息,可参考CSDN博客链接。

spring启动原理(spring工程启动)

       SpringBoot启动原理分析

       è‡ªåŠ¨é…ç½®æ ¸å¿ƒç±»SpringFactoriesLoader

       ä¸Šé¢åœ¨è¯´@EnableAutoConfiguration的时候有说META-INF下的spring.factories文件,那么这个文件是怎么被spring加载到的呢,其实就是SpringFactoriesLoader类。

       SpringFactoriesLoader是一个供Spring内部使用的通用工厂装载器宏闭,SpringFactoriesLoader里有两个方法,

       åœ¨è¿™ä¸ªSpringBoot应用启动过程中,SpringFactoriesLoader做了以下几件事:

       åŠ è½½æ‰€æœ‰META-INF/spring.factories中的Initializer

       åŠ è½½æ‰€æœ‰META-INF/spring.factories中的Listener

       åŠ è½½EnvironmentPostProcessor(允许在Spring应用构建之前定制环境配置)

       æŽ¥ä¸‹æ¥åŠ è½½Properties和YAML的PropertySourceLoader(针对SpringBoot的两种配置文件的加载器)

       å„种异常情况的FailureAnalyzer(异常解释器)

       åŠ è½½SpringBoot内部实现的各种AutoConfiguration

       æ¨¡æ¿å¼•æ“ŽTemplateAvailabilityProvider(如Freemarker、Thymeleaf、Jsp、Velocity等)

       æ€»å¾—来说,SpringFactoriesLoader和@EnableAutoConfiguration配合起来,整体功能就是查找spring.factories文件,加载自动配置类。

       æ•´ä½“启动流程

       åœ¨æˆ‘们执行入口类的main方法之后,运行SpringApplication.run,后面new了一个SpringApplication对象,然后执行它的run方法。

       åˆå§‹åŒ–SpringApplicationç±»

       åˆ›å»ºä¸€ä¸ªSpringApplication对象时,会调用它自己的initialize方法

       æ‰§è¡Œæ ¸å¿ƒrun方法

       åˆå§‹åŒ–initialize方法执行完之后,会调用run方法,开始启动SpringBoot。

       é¦–先遍历执行所有通过SpringFactoriesLoader,在当前classpath下的META-INF/spring.factories中查找所有可用的SpringApplicationRunListeners并实例化。调用它们的starting()方法,液蔽通知这些监听器SpringBoot应用启动。

       åˆ›å»ºå¹¶é…ç½®å½“前SpringBoot应用将要使用的Environment,包括当前有效的PropertySource以及Profile。

       éåŽ†è°ƒç”¨æ‰€æœ‰çš„SpringApplicationRunListeners的environmentPrepared()的方法,通知这些监听器SpringBoot应用的Environment已经完成初始化。

       æ‰“印SpringBoot应用的banner,SpringApplication的showBanner属性为true时,如果classpath下存在banner.txt文件,则打印其内容,否则打印默认banner。

       æ ¹æ®å¯åŠ¨æ—¶è®¾ç½®çš„applicationContextClass和在initialize方法设置的webEnvironment,创建对应的applicationContext。

       åˆ›å»ºå¼‚常解析器,用在启动中发生异常的时候进行异常处理(包括记录日志、释放资源等)。

       è®¾ç½®SpringBoot的Environment,注册SpringBean名称的序列化器BeanNameGenerator,并设置资源加载器ResourceLoader,通过SpringFactoriesLoader加载ApplicationContextInitializer初始化器,调用initialize方法,对创建的ApplicationContext进一步初始化。

       è°ƒç”¨æ‰€æœ‰çš„SpringApplicationRunListeners的contextPrepared方法,通知闹绝州这些Listener当前ApplicationContext已经创建完毕。

       æœ€æ ¸å¿ƒçš„一步,将之前通过@EnableAutoConfiguration获取的所有配置以及其他形式的IoC容器配置加载到已经准备完毕的ApplicationContext。

       è°ƒç”¨æ‰€æœ‰çš„SpringApplicationRunListener的contextLoaded方法,加载准备完毕的ApplicationContext。

       è°ƒç”¨refreshContext,注册一个关闭Spring容器的钩子ShutdownHook,当程序在停止的时候释放资源(包括:销毁Bean,关闭SpringBean的创建工厂等)

       æ³¨ï¼šé’©å­å¯ä»¥åœ¨ä»¥ä¸‹å‡ ç§åœºæ™¯ä¸­è¢«è°ƒç”¨ï¼š

       1)程序正常退出

       2)使用System.exit()

       3)终端使用Ctrl+C触发的中断

       4)系统关闭

       5)使用Killpid命令杀死进程

       èŽ·å–当前所有ApplicationRunner和CommandLineRunner接口的实现类,执行其run方法

       éåŽ†æ‰€æœ‰çš„SpringApplicationRunListener的finished()方法,完成SpringBoot的启动。

       spring工作原理

       Spring的工作原理是让一个对象的创建不用new就可以自动的生产,在运行时与xmlSpring的配置文件来高岩动态的创建对象和调用对象,而不需要通过代码来关联。

       Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。

       spring特点是1.方便解耦,简化开发。2.AOP编程的支持。3.声明式事务的支持。4.方便程序的测试。5.方便集成各种优秀框架。6.降低JavaEEAPI的使用难度。7.Java源码是经典学习范例。

       Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中带消受益。Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

       Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初戚行御始化时不等对象请求就主动将依赖传递给它。

spring的原理是什么?

       ä¸€ã€IoC(Inversionofcontrol):控制反转\x0d\1、IoC:\x0d\概念:控制权由对象本身转向容器;由容器根据配置蠢衫文件去创建实例并创建各个实例之间的依赖关系\x0d\核心:bean工厂;在Spring中,bean工厂创建的各个实例称作bean\x0d\二、AOP(Aspect-OrientedProgramming):面向方面编程。\x0d\1、代理的两种方式:\x0d\静态代理:\x0d\针对每个具体类分别编写代理类。\x0d\针对一个接口编写一个代理类。\x0d\动态代理:\x0d\针对一个方面编写一个InvocationHandler,然后借用JDK反射包中的Proxy类为各种接口动态生成相应的代理类。\x0d\2、AOP的主要原理:动态代理。\x0d\Spring工作原理\x0d\Spring已经用过一段时间了,感觉Spring是个很不错的框架。内部最核心的就是IOC了,\x0d\动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射,反射其实就是在运行时动态的去创建、调用对象,Spring就是在运行时,跟xmlSpring的配置文件来动态的创建对象,和调用对象里的方法的。\x0d\Spring还有一个核心就是AOP这个就是面向切面编程,可以为某一类对象进行监督和控制(也就是在调用这类对象的具体方法的前后去调用你指定的模块)从而达到对一个模块扩充的功能。这些都是通过配置类达到谈庆的。\x0d\Spring目的含档握:就是让对象与对象(模块与模块)之间的关系没有通过代码来关联,都是通过配置类说明管理的(Spring根据这些配置内部通过反射去动态的组装对象)\x0d\要记住:Spring是一个容器,凡是在容器里的对象才会有Spring所提供的这些服务和功能。\x0d\Spring里用的最经典的一个设计模式就是:模板方法模式。

SpringBoot应用启动原理(二)扩展URLClassLoader实现嵌套jar加载

       åœ¨ä¸Šç¯‡æ–‡ç« ã€ŠSpringBoot应用启动原理(一)将启动脚本嵌入jar》中介绍了SpringBoot如何将启动脚本与RunnableJar整合为ExecutableJar的原理,使得生成的jar/war文件可以直接启动

       æœ¬ç¯‡å°†ä»‹ç»SpringBoot如何扩展URLClassLoader实现嵌套jar的类(资源)加载,以启动我们的应友枣旁用。

       é¦–先岩伏,从一个简单的示例开始

       build.gradle

       WebApp.java

       æ‰§è¡Œgradlebuild构建jar包,里面包含应用程序、第三方依赖以及SpringBoot启动程序,其目录结构如下

       æŸ¥çœ‹MANIFEST.MF的内容(MANIFEST.MF文件的作用请自行GOOGLE)

       å¯ä»¥çœ‹åˆ°ï¼Œjar的启动类为org.springframework.boot.loader.JarLauncher,而并不是我们的com.manerfan.SpringBoot.theory.WebApp,应用程序入口类被标记为了Start-Class

       jar启动并不是通过应用程序入口类,而是通过JarLauncher代理启动。其实SpringBoot拥有3中不同的Launcher:JarLauncher、WarLauncher、PropertiesLauncher

       SpringBoot使用Launcher代理启动,其最重要的一点便是可以自定义ClassLoader,以实现对jar文件内(jarinjar)或其他路径下jar、class或资源文件的加载

       å…³äºŽClassLoader的更多介绍可参考《深入理解JVM之ClassLoader》

       SpringBoot抽象了Archive的概念,一个Archive可以是jar(JarFileArchive),可以是一个文件目录(ExplodedArchive),可以抽象为统一访问资源的逻辑层。

       ä¸Šä¾‹ä¸­ï¼Œspring-boot-theory-1.0.0.jar既为一个JarFileArchive,spring-boot-theory-1.0.0.jar!/BOOT-INF/lib下的每一个jar包也是一个JarFileArchive

       å°†spring-boot-theory-1.0.0.jar解压到目录spring-boot-theory-1.0.0,则目录spring-boot-theory-1.0.0为一个ExplodedArchive

       æŒ‰ç…§å®šä¹‰ï¼ŒJarLauncher可以加载内部/BOOT-INF/lib下的jar及/BOOT-INF/classes下的应用class

       å…¶å®žJarLauncher实现很简单

       å…¶ä¸»å…¥å£æ–°å»ºäº†JarLauncher并调用父类Launcher中的launch方法启动程序

       å†åˆ›å»ºJarLauncher时,父类ExecutableArchiveLauncher找到自己所在的jar,并创建archive

       åœ¨Launcher的launch方法中,通过以上archive的getNestedArchives方法找到/BOOT-INF/lib下所有jar及/BOOT-INF/classes目录所对应的archive,通过这些archives的url生成LaunchedURLClassLoader,并将其设置为线程好橡上下文类加载器,启动应用

       è‡³æ­¤ï¼Œæ‰æ‰§è¡Œæˆ‘们应用程序主入口类的main方法,所有应用程序类文件均可通过/BOOT-INF/classes加载,所有依赖的第三方jar均可通过/BOOT-INF/lib加载

       åœ¨åˆ†æžLaunchedURLClassLoader前,首先了解一下URLStreamHandler

       java中定义了URL的概念,并实现多种URL协议(见URL)*ponentClasses)。在使用XML配置方式时,通过new ClassPathXmlApplicationContext("classpath:spring.xml")来创建实例,其中需要指定xml配置文件路径。使用注解方式时,也需要为ApplicationContext提供起始配置源头,这里使用配置类代替xml配置文件,按照配置类中的注解(如@ComponentScan、@Import、@Bean)解析并注入Bean到IoC容器。

       通过配置类,Spring解析注解实现Bean的注入。使用@Configuration注解定义的配置类相当于xml配置文件,但目前Spring推荐使用注解方式,xml配置的使用概率正在降低。

       register(componentClasses)方法的核心逻辑在AnnotatedBeanDefinitionReader#doRegisterBean中,将传入的配置类解析为BeanDefinition并注册到IoC容器。ConfigurationClassPostProcessor这个BeanFactory后置处理器在IoC初始化时,获取配置类的BeanDefinition集合,开始解析。

       真正启动IoC容器的流程在refresh()方法中,这是了解IoC容器启动流程的关键步骤。refresh方法在AbstractApplicationContext中定义,采用模板模式,提供IoC初始化流程的基本实现,子类可以扩展。

       下面分析refresh()方法的每个步骤,以了解IoC容器的启动流程。

       prepareRefresh方法主要在refresh执行前进行准备工作,如设置Context的启动时间、状态,以及扩展系统属性相关。

       initPropertySources()方法主要用于扩展配置来源,如网络、物理文件、数据库等加载配置信息。StandardEnvironment默认只提供加载系统变量和应用变量的功能,用于子类扩展。

       ❝initPropertySources方法常见扩展场景包括:❞

       getEnvironment().validateRequiredProperties()确保设置的必要属性在环境中存在,否则抛出异常终止应用。

       BeanFactory是Spring的基本IoC容器,ApplicationContext包装了BeanFactory,提供更智能、更便捷的功能。ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();获取的BeanFactory是IoC容器初始化工作的基础。

       上面获取的BeanFactory还不能直接使用,需要填充必要的配置信息。至此,IoC容器的启动流程基本完成。

       这里对IoC启动流程有个大致、直观的印象。主要步骤包括:准备阶段、配置来源扩展、初始化BeanFactory、填充配置、解析配置类、注册Bean、实例化BeanPostProcessor、初始化国际化和事件机制、以及创建内嵌Servlet容器(在SpringBoot中实现)。这些步骤确保了IoC容器顺利启动并管理Bean。