1.springboot如何启动内置tomcat?(源码详解)
2.yarn源码分析(四)AppMaster启动
3.SpringBoot源码 | refreshContext方法解析
4.Spring源码- 02 Spring IoC容器启动之refresh方法
5.Tomcat处理http请求之源码分析 | 京东云技术团队
6.Servlet源码和Tomcat源码解析
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`协同工作。启动过程本质上是一个链式调用,每个组件的初始化和启动都会触发下一层组件的逻辑。
yarn源码分析(四)AppMaster启动
在容器分配完成之后,启动容器的代码主要在ContainerImpl.java中进行。通过状态机转换,container从NEW状态向其他状态转移时,会调用RequestResourceTransition对象。RequestResourceTransition负责将所需的资源进行本地化,或者避免资源本地化。若需本地化,还需过渡到LOCALIZING状态。为简化理解,此处仅关注是否进行资源本地化的情况。
为了将LAUNCH_CONTAINER事件加入事件处理队列,调用了sendLaunchEvent方法。该事件由ContainersLauncher负责处理。ContainersLauncher的handle方法中,使用一个ExecutorService(线程池)容器Launcher。ContainerLaunch实现了Callable接口,其call方法生成并执行launch_container脚本。以MapReduce框架为例,该脚本在hadoop.tmp.dir/application name/container name目录下生成,其主要作用是启动MRAppMaster进程,即MapReduce的spynote源码搭建ApplicationMaster。
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`方法配置工厂标准的上下文特征,如上下文类加载器、lisp注册源码后置处理器等。`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源码- Spring IoC容器启动之refresh方法
在注册阶段,AnnotationConfigApplicationContext构造方法中的第一个方法被分析过。接下来,我们关注第二个方法:register(componentClasses)。蓝牙源码传输在使用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。
Tomcat处理putePodActions()`函数中的`containerChanged()`函数。该函数通过比较容器结构元素的HASH值来判断容器是否发生变化,进而决定是否重启。
原因解析
kubelet升级后,不同版本的容器结构可能包含额外的成员,如`VolumeDevices`等。这些新增成员导致在进行HASH计算时,升级前后的HASH值不一致,从而触发容器的重启。
解决方案
为了避免容器因版本升级而自动重启,可以记录并持久化kubelet版本信息与启动时间。在计算容器结构的HASH值时,参考持久化信息来判断是否忽略重启操作。通过修改源代码,实现这一方案,代码示例可参考GitHub上的补丁文件。
适用场景及注意事项
此方案适用于在kubelet版本升级情况下,希望容器服务持续运行不重启的业务场景。但在实现中需要注意以下几点:
1. 在版本升级前,需对比不同版本容器结构的变化,了解版本升级对容器HASH计算的影响。
2. 采用记录并缓存kubelet版本及启动时间至本地文件的方法,可能因文件损坏导致容器服务仍重启。可临时手动生成文件作为备份。
3. 每次版本升级前需更新源码并重新编译生成二进制文件,这一过程较为繁琐。
总结
通过解析自kubelet启动至容器服务重启的调用链路,确认了版本升级后引起容器重启的判断条件及处理逻辑。同时,提供了解决方案以避免容器因版本升级而重启,这一方法有助于解决生产环境中关键业务无服务中断的问题。尽管存在一些注意事项,但通过代码修改和适当的规划,可以实现稳定、高效的容器服务运行。
Tomcat源码分析— Bootstrap启动流程
在探讨Tomcat启动流程之前,需要理解其组件及其周期状态,这为后续深入学习组件初始化与启动等提供了基础。
实现Lifecycle接口的组件拥有种状态。Bootstrap作为Tomcat启动入口类,负责构造类加载器以加载Catalina内部类,通过查找catalina.home目录下所有jar包,确保安全地加载应用程序类。
通过Bootstrap的main方法启动Tomcat实例,主要步骤包括创建Bootstrap对象、调用init方法,并根据启动参数执行load和start方法。
Bootstrap的init方法初始化类加载器,使得Tomcat能加载应用程序类,同时设置当前线程上下文加载器为CatalinaLoader。initClassLoaders方法创建三种类加载器,其中catalinaLoader与sharedLoader的父加载器为commonLoader。完成初始化后,预加载tomcat和javax包下的自定义类,避免访问权限异常。
调用catalinaLoader加载器加载Catalina类,通过反射实例化对象,并设置sharedLoader实例作为入参,最后将实例化的Catalina对象赋予catalinaDaemon成员变量。
Tomcat组件的初始化主要在load方法中完成,通过反射调用Catalina的load方法,构建并初始化StandardServer及其子组件。Bootstrap.load方法通过反射调用Catalina的load方法,Catalina的load方法实现序列图中的逻辑,初始化配置文件解析器Digester,构建standardServer实例,绑定当前catalina实例,设置根路径,并调用init方法完成初始化。
Tomcat中的容器或组件使用模板方法设计模式,子类通过重写LifecycleBase抽象类的模板方法initInternal实现初始化逻辑。LifecycleBase的init方法主要完成两件事:调用父类的LifecycleBase#init方法,由standerServer#initInternal方法执行实际初始化。init方法逻辑包括:执行LifecycleBase#initInternal抽象方法,由standardServer#initInternal方法完成初始化。
service组件的init方法主要初始化Connector连接器,连接器的初始化尤为重要。不同协议处理器如AjpAprProtocol、HttpNioProtocol的初始化流程将在后续文章中单独讲解。
Bootstrap类的main方法通过反射执行catalina实例的start方法,启动standardServer实例,使其监听端口并接收新请求。start方法主要逻辑包括启动Service、Engine容器、Executor执行器、MapperListener监听器、Connector连接器等组件。当启动成功后,创建并监听端口,Tomcat对外提供服务。
总结,Tomcat的启动流程清晰且依赖模板方法与责任链设计模式,理解这两种模式有助于更好地理解启动过程及代码。启动过程首先初始化各组件,如Server、Service、Engine容器、虚拟主机Host、上下文Context、Executor执行器、Connector连接器等,然后按顺序启动组件,成功后监听端口提供服务。