全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

中高端软件定制开发服务商

与我们取得联系

13245491521     13245491521

2024-01-27_概览SpringBoot的run方法主干逻辑

您的位置:首页 >> 新闻 >> 行业资讯

概览SpringBoot的run方法主干逻辑 ? ?点击关注公众号,”技术干货”及时达!???思考,输出,沉淀。用通俗的语言陈述技术,让自己和他人都有所收获。 作者:毅航?? ?对于SpringBoot中run方法的分析网上已经有很多教程了,本文想试着从全局出发,重新梳理SpringBoot中run方法的整体脉络,使你不至于过分专注细节而迷失在run方法繁琐的调用逻辑中。 前言SpringBoot是基于Spring开发的一种轻量级的全新框架,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring 应用的整个搭建和开发过程。 开发者可以通过SpringBoot轻松地创建独立的,基于生产级别的基于Spring的应用程序。SpringBoot的出现极大的降低了开发应用的难度。除此之外,SpringBoot还具有如下特点: 可独立运行的Spring项目:Spring Boot可以以jar包的形式独立运行。 内嵌的Web容器:Spring Boot可以选择内嵌Tomcat、Jetty或者Undertow,无须以war包形式部署项目。 简化的Maven配置:Spring提供推荐的基础 POM 文件来简化Maven 配置。 自动配置: SpringBoot会根据项目依赖来自动配置Spring、SpringMVC等框架,极大地减少项目要使用的配置。 构建SpringBoot项目如果你曾经有过Spring、SpringMVC的开发经验,你一定会对其中繁琐的xml配置感到深恶痛绝,而SpringBoot的出现恰好可以解决这一痛点问题,SpringBoot可以让你更加快捷的搭建一个企业级应用。具体代码如下: importorg.mybatis.spring.annotation.MapperScan; importorg.springframework.boot.SpringApplication; importorg.springframework.boot.autoconfigure.SpringBootApplication; /** *SpringBoot应用启动类 **/ @SpringBootApplication publicclassLearnSpringBootApplication{ publicstaticvoidmain(String[]args){ //启动SpringBoot SpringApplication.run(LearnSpringBootApplication.class,args); } } 通过上述代码不难发现,启动一个SpringBoot应用非常简单,我们只需如下几步: 提供一个SpringBoot的启动类LearnSpringBootApplication(注:启动类的名称可任意指定)在启动类上标注一个@SpringBootApplication注解编写一个main方法,调用SpringApplication中的run方法经过上述三步操作,就可以构建出一个简单的SpringBoot应用,随后运行main方法即可启动一个SpringBoot的应用。 可以注意到,在main方法中仅需调用一个run方法就能完成SpringBoot应用的启动。那这个run方法背后究竟又做了那些操作呢?接下来,我们便聚焦在SpringApplication的run方法中,看看run方法背后完成了那些操作。 run方法背后的逻辑进入到SpringApplication的run方法后,其最终入调用到如下的方法信息,相关代码如下所示: ?SpringApplication # run ? publicstaticConfigurableApplicationContextrun(ClassprimarySource,String...args){ returnrun(newClass[]{primarySource},args); } publicstaticConfigurableApplicationContextrun(Class[]primarySources,String[]args){ returnnewSpringApplication(primarySources).run(args); } 可以看到SpringApplication中对方法进行了重载,其最终会调用到run(Class[] primarySources, String[] args)。 此处run方法逻辑包含了两个操作: 构建一个SpringApplication对象执行SpringApplication对象的run方法信息接下来,我们将围绕上述的两个操作展开分析SpringBoot中run方法背后的逻辑。 创建SpringApplication对象publicSpringApplication(Class...primarySources){ this(null,primarySources); } publicSpringApplication(ResourceLoaderresourceLoader,Class...primarySources){ this.resourceLoader=resourceLoader; Assert.notNull(primarySources,"PrimarySourcesmustnotbenull"); this.primarySources=newLinkedHashSet(Arrays.asList(primarySources)); this.webApplicationType=WebApplicationType.deduceFromClasspath(); setInitializers((Collection)getSpringFactoriesInstances(ApplicationContextInitializer.class)); setListeners((Collection)getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass=deduceMainApplicationClass(); } 可以看到对于SpringApplication而言,其在构建时包含如下信息的构建: ResourceLoader 指明资源加载器,这个暂时不用太过关注,应为其默认为null。webApplicationType 推断当前web应用类型,可通过一个deduceFromClasspath方法推断出的。随后设置了setInitializers、setListeners两个列表,分别是一堆Initializer和Listener,其都是通过getSpringFactoriesInstances方法获取。此外,还通过primarySources、mainApplicationClass记录了启动主要资源类,也就是之前传入的LearnSpringBootApplication.class。面对上述代码中诸多的陌生对象,你肯定什么都不清楚,不知道每个变量有什么用,是干嘛的,这没有关系。因为第一次分析你只要熟悉它的脉络就可以。知道在SpringApplication的构造方法中,会设置两个集合变量Initializer和Listener,了解这些就够了。 等之后你有时间,再逐个去了解每个变量或者组件的作用就可以了。事实上,SpringApplication的创建时的细节分析 你可以慢慢拆解上面的每一步,单独看看每一个组件大体是作什么的,这就属于细节研究了。 比如,你可以研究下ResourceLoader是什么?通过阅读它的类注释后可以发现,ResourceLoader 类负责使用ClassLoader加载ClassPath下的class和各种配置文件的。 对于webApplicationType类型如何被推断的?其本质就是根据几个静态变量定义的类全限定名称来进行判断的。具体而言,其会判断classPath下是否存在DispatcherServlet、DispatcherHandler等类来推断出类型。如果使用了web-starter则默认推断出为Servlet类型的应用。 至于primarySources、mainApplicationClass这个两个变量记录了启动类信息LearnSpringBootApplication.class, 其目的在于为了后续扫描包路径信息,完成自动配置等考虑的。 至于最后两个集合变量Initializer和Listener如何设置的,则比较考验阅读源码的能力了。其基本原理是通过ClassLoader扫描了classPath下所有META-INF/spring.factories这个目录中的文件,通过指定的factoryType,也就是接口名称,获取对应的所有实现类,并且实例化成对象,返回成一个list列表。比如, factoryType=ApplicationContextInitializer 就返回这个接口在META-INF/spring.factories定义的所有的实现类,并实例化为一个列表List ApplicationContextInitializer 。ApplicationListener同理。这里面其实有很多细节,大量使用了类加载器、缓存机制,反射机制等,有兴趣的话可以仔细研究下。 总结来看,上述构建SpringApplication的过程虽然会包括很多东西,但别慌,其概括成一句话就是:设定某些属性信息,然后通过classLoader获取classPath下指定位置某些接口的实现类和实例对象列表。 进一步, 构建SpringApplication时的相关逻辑如图所示: 熟悉了SpringApplication 的创建,接着我们该分析它的run(String ... args) 方法了。 SpringApplication Run的脉络run(String... args) 的逻辑如下: publicConfigurableApplicationContextrun(String...args){ //.......省略其他无关代码 listeners.starting(); try{ //构建一个应用参数解析器 ApplicationArgumentsapplicationArguments=newDefaultApplicationArguments(args); //加载系统的属性配置信息 ConfigurableEnvironmentenvironment=prepareEnvironment(listeners,applicationArguments); //用于控制是否忽略BeanInfo的配置 configureIgnoreBeanInfo(environment); //打印banner信息 BannerprintedBanner=printBanner(environment); //创建一个容器,类型为ConfigurableApplicationContext context=createApplicationContext(); exceptionReporters=getSpringFactoriesInstances(SpringBootExceptionReporter.class, newClass[]{ConfigurableApplicationContext.class},context); //容器准备工作(可暂时忽略) prepareContext(context,environment,listeners, //解析传入参数信息 applicationArguments,printedBanner); //容器刷新(重点关注) refreshContext(context); afterRefresh(context,applicationArguments); } //.......省略其他无关代码 returncontext; } 我们重点分析其中的refresh方法信息,对于refresh而言,其调用逻辑如下所示: (注:如果你熟悉Spring中容器刷新的操作流程,相信你一定会秒懂图中蓝色方框内逻辑) 进一步,上面代码虽然看着复杂, 但本质主要就是执行了一堆方法。从方法名字看出,都是围绕Context、Environment这些术语。也就是围绕容器和配置文件组织的逻辑。另外,SpringBoot整个run方法中有几个很关键扩展点,设计SpringApplicationRunListeners、Runners等扩展入口。此外容器创建、刷新等也要各自的扩展点,对容器的增强扩展,如beanFactoryPostProcessor,对Bean的增加扩展,如beanPostProcessor。 (注:原图地址:https://baijiahao.baidu.com/s?id=1713152880461432834) 最后通过一张图来概括上面run方法脉络,其中: 黑色部分直观的反映了扩展逻辑相关逻辑白色部分是run方法每个方法的字面理解,只是每一步有很多扩展点和做的事情比较多,让你感觉会有点云里雾里的。蓝色部分,概括了核心逻辑。也就是SpringBoot启动,说白了我们核心就是要找到这三点:「自动装配配置、Spring容器的创建、web容器启动。」总结如果你第一次接触SpringBoot源码,可能会感到有些"不适"。这一定程度上是因为你过多的关注了源码细节,事实上,从细节中可以学习到知识,同时从主干脉络上也能学到知识。 而本文的主要作用是先为了梳理清楚一个run方法的脉络信息,让你熟悉run脉络的启动逻辑,让你清楚run的主干逻辑,之后如果你有兴趣要继续深入研究SpringBoot的启动逻辑只需沿着这一主干分析即可。 阅读原文

上一篇:2022-08-14_成就百年品牌 | 华与华20周年,华杉演讲实录 下一篇:2019-11-25_5种高效利用value-counts函数的方法,一键提升数据挖掘姿势水平

TAG标签:

19
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版域名注册主机空间手机网站建设网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。
项目经理在线

相关阅读 更多>>

猜您喜欢更多>>

我们已经准备好了,你呢?
2022我们与您携手共赢,为您的企业营销保驾护航!

不达标就退款

高性价比建站

免费网站代备案

1对1原创设计服务

7×24小时售后支持

 

全国免费咨询:

13245491521

业务咨询:13245491521 / 13245491521

节假值班:13245491521()

联系地址:

Copyright © 2019-2025      ICP备案:沪ICP备19027192号-6 法律顾问:律师XXX支持

在线
客服

技术在线服务时间:9:00-20:00

在网站开发,您对接的直接是技术员,而非客服传话!

电话
咨询

13245491521
7*24小时客服热线

13245491521
项目经理手机

微信
咨询

加微信获取报价