当前位置:   article > 正文

SpringBoot初识

SpringBoot初识

SpringBoot初识

简介

SringBoot是基于Spring开发的,它本身并不提供Spring框架的核心特性及扩展功能,只是用来快速、敏捷地开发基于Spring框架的应用。换句话说,SpringBoot并不是用来替代Spring的解决方案,而是和Spring框架紧密贴合用于提升Spring开发者体验的工具。SpringBoot以约定大于配置的核心思想,默认已经配置了许多设置,多数SprinBoot应用开发时只需要少量Spring配置,同时它也集成了许多常用的第三方配置(例如Redis、MongoDB、Quartz)等,SpringBoot应用中这些第三方库几乎可以零配置开箱即用。

简单来说,SpringBoot并不算是新框架,它默认已经配置好了很多框架的使用方式,就像maven整合了很多jar包,SpringBoot整合了很多框架。

SpringBoot的主要优点:

  • 为所有Spring开发者更快的入门
  • 开箱即用,提供各种默认配置来简化项目配置
  • 内嵌式容器简化Web项目
  • 没有冗余代码生成和XML配置的要求

快速生成一个SpringBoot项目

生成一个SpringBoot项目非常方便,可以分为两种方式,一种是通过在Spring官网:https://spring.io生成项目后下载到本地,再通过IDE导入(适用于Eclipse)
在这里插入图片描述
再官网的Projects选项中找到Spring initializr
在这里插入图片描述
接下来填写好自己的项目名称、包名版本号等,右边的Dependencies可以选择项目需要添加哪些依赖,如果在此处没配置,新建项目后再往pom.xml里面加也是一样的。都填写好后点击下方的GENARATE,稍后会弹出下载提示,这就是一个SpringBoot项目了。下载完后解压,得到一个完整的项目,通过IDE导入,一个SpringBoot项目就建好了。
而如果使用IDEA的小伙伴,在IDEA中已经集成了快速生成插件,可以直接在IDEA中New-Project,然后选择Spring Initializr(注意IDEA需要是旗舰版本才支持):
在这里插入图片描述
可以看到该界面与官网基本无差,稍微不同的是顶部新出现了一个Server URL,这里是选择生成器的地址,一般选择官网地址:https://start.spring.io即可,但因为官网地址在国外,有时候因为网络原因官网地址会连接不上,就可以像我一样,选择国内的阿里云快速启动地址也是一样的。并且后续的选项也会是中文,这里看大家自己选择了。接下来点击next,进入到依赖选择界面:
在这里插入图片描述
可以看到因为我使用的是阿里云的快速启动,这个界面和官网除了中文不同以外,还多出了许多阿里云相关的技术,这里依赖大家根据需要自行选择,这里是新建一个demo项目,就先选择一个SpringWeb依赖即可,最后点击finish,项目就生成了。

项目结构

默认的项目结构是这样:
在这里插入图片描述

  • java目录中存放包、源码,resources中存放项目相关的配置文件以及静态资源。
  • static目录存放静态资源,templates目录为thymeleaf模板读取html文件的默认路径,这里放在后面的文章中会详细讲到。
  • application.properties为项目的配置文件,相比于SSM框架的各种配置文件,SpringBoot对于项目的配置文件就只需要一个,简化了许多,而官方推荐使用的是另一种格式配置文件yaml,这也放在后续的文章细说。

不同于之前的Web项目,SpringBoot连Web服务器也封装在了项目中,默认封装的是Tomcat,一个SpringBoot项目就是一个独立的Web应用,当然如果想要更换Web服务器,或是想像之前的web开发一样,不需要内置Web服务器,也可以在pom中进行配置脱离Web服务器,这里就不细讲了。

启动类

源码中的***Application类便是SpringBoot的启动类了,通过它来启动一个SpringBoot项目,打开这个类:

在这里插入图片描述
发现这个类很简单,通过main方法中的SpringAppliction.run方法启动项目,在后面我们稍微对它进行分析,先启动它:
在这里插入图片描述
控制台中输出了一些项目启动信息后,看到最后一行Started…便是启动成功了,打开浏览器访问该项目,在没有进行任何配置时,通过localhost:8080便可访问:
在这里插入图片描述
因为我们没有写任何页面以及接口,所以出现了该报错信息。但项目已经成功访问了。

自动装配

SpringBoot相比于传统Spring框架最大的不同就是省去了各种繁琐的配置文件编写,原因是它默认已经帮我们配置好了常用的设置,接下来简单的了解下SpringBoot是如何进行这些自动配置的,那么首先就从pom.xml文件说起:

pom

在pom的顶部可以看到一个parent父节点,表示此项目继承了其中的父工程:
在这里插入图片描述
而点开该工程spring-boot-starter-parent,而它还有一个父节点:
在这里插入图片描述
再次点开:
在这里插入图片描述
这次终于到底了,所以可以得出结论的是,一个SpringBoot项目的父工程实际上是spring-boot-dependencies,而根据它的名字以及查看其中的配置项不难看出:
在这里插入图片描述
spring-boot-dependencies这一工程中管理着许多常用依赖需要的版本,而正是因为在这里配置了这些版本号,我们在引入某些依赖的时候可以不需要写版本号,使用的便是它为我们写好的版本号。但如果我们使用的是其中没有配置到的依赖,那么就必须要写版本号了。再看回到spring-boot-starter-parent工程:在这里插入图片描述

不难发现该工程中配置的是与项目相关的信息,拿图中的这一条打比方,在resuorce节点中配置了过滤指定目录src/main/resources下的yml、yaml、properties文件,而该目录下的这些文件实际上就是项目的配置文件,正因为这里与我们约定好了,所以我们得在约定好的位置、用约定好的文件格式,才能被项目识别。而其他许多的自动配置,也都是以这种约定的方式帮我们完成的。这就是约定大于配置的体现。浏览完spring-boot-starter-parent的pom,可以总结出该工程的作用:

  • 定义项目的编译版本,比如此处项目定义的是JDK1.8
  • 使用何种编码格式,比如此处指定的是UTF-8
  • maven源文件和目标文件编译的版本
  • 执行打包操作时的配置,比如在此处将jar与war两种打包方式都启用了

归结成一句话,因为该父工程中默认配置的存在,我们不再需要手动配置许多诸如项目路径、资源等选项,而更专注于编码。

启动器

如果仔细看pom中的依赖,会发现许多依赖的名字都有一定规律:
在这里插入图片描述
他们的名字都是以spring-boot-starter-***格式命名,那么其中肯定存在一些联系,那么分别点开这两个工程:
在这里插入图片描述
在这里插入图片描述
发现他们第一个依赖都是相同的,都是spring-boot-starter,那么再点进这个工程一探究竟:
在这里插入图片描述

此时不难发现,该工程中包含的依赖都是一些项目所需的依赖了,比如spring-boot,类似于之前spring的核心依赖,这是springboot的核心依赖,如果再点进去看发现它实际上就是将spring的核心依赖集成在了一起。以及下面的spring-boot-autoconfigure,从名字就能看出,他是与springboot自动配置相关的依赖。该jar是SpringBoot能进行自动配置的核心,稍后我们会提到。

再次回到刚刚及的这两个工程,浏览其中的依赖,就很容易知道其作用了:

  • spring-boot-starter-web:包含了项目中与web相关的依赖,比如数据交互时需要用到的json:
    在这里插入图片描述
    以及web服务器Tomcat:
    在这里插入图片描述
    等等,再看另一个:
  • spring-boot-starter-test:包含了与项目测试相关所需的jar包
    在这里插入图片描述
    因此不难得出结论:
    以spring-boot-starter开头的依赖,会导入项目相关模块所需要的依赖,比如上面的web模块、test模块等等。而它们必须导入核心启动器spring-boot-starter。

SpringBoot将所有的功能场景都抽出来,做成了类似上图中的一个个的starter供开发者使用,开发者需要何种功能,只需引入启动器即可,目前主流的功能都已经有了相关的启动器,但也有少数第三方jar并不是以该规则命名的。

主启动类

主启动类即一个SpringBoot应用启动的入口,从代码上看它非常简洁,一个注解,一个main方法,但在你启动它的一瞬间,实际上是做了许多工作的。
在这里插入图片描述
先从注解看起:
@SpringBootApplication:该注解的作用是标注该类是一个SpringBoot应用的启动类,通过该类的主方法启动SpringBoot启动应用。而点进该注解,发现它长这样:
在这里插入图片描述
首先被四个元注解修饰,这是注解类的基本,就不一一解释了。重点在后面三个注解,一一来看:

@SpringBootConfiguration
从名字来看该注解应该是与配置相关,点进去再看:
在这里插入图片描述
此时发现该配置类被@Configuration注解修饰了,也就是说明标注该类为一个配置类,会被加载到Spring容器中,而再点进@Configuration注解:
在这里插入图片描述
被@Component注解修饰,不难看出该注解的实质其实是一个组件,到这里注解也就到底了,于是回到最初的@SpringBootConfiguration注解,我们可以归纳出该注解的作用:

  • 是SpringBoot应用的配置类
  • 其实质还是Spring的一个组件,启动时会被注入到Spring容器中,交给Spring加载配置

@EnableAutoConfiguration
同样,先从其字面意思理解,应该是与自动配置相关的注解,并且加上它之后应该是启用该功能。同样点进这个注解:
在这里插入图片描述
该注解中又包含了两个注解:
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)

先点进@AutoConfigurationPackage注解看看:
在这里插入图片描述
从名字来看,能大致猜出,该注解应该是与自动配置包相关的,而在该注解中的又通过@Import注解导入了一个名为AutoConfigurationPackages配置类中的静态内部类Registrar,再点进去看看:
在这里插入图片描述
查看两个方法,发现中的参数都包含一个名为PackageImports的类,于是点进这个类,发现它就在下面:

在这里插入图片描述

下一个断点,在调试窗口中发现:
在这里插入图片描述
此处获取到了启动类的全类名,也就是说明,Registary类实际上是把SpringBoot的启动类所在的包进行了扫描,再依据该类上给我们的注释:
在这里插入图片描述
结合在网上搜索的资料,得出@AutoConfigurationPackage注解的作用:
将启动类所在的包以及子包下的组件扫描到Spring容器中,他类似于在之前 spring配置文件中的<context:component-scan base-package=“org.example”/>节点。
再看另一个注解@Import(AutoConfigurationImportSelector.class),这与上面的@Import注解类似,又导入了一个名为AutoConfigurationImportSelector的配置类,点进去这个类:
在这里插入图片描述
由于该类方法众多,就不一一解释了,主要看一下这个方法:
在这里插入图片描述
方法中第一行调用了SpringFactoriesLoader类中的loadFactoryName方法,而了解过该类的小伙伴知道,该类可以在META-INF/spring.factories配置文件中读取相应的jar,并实例化成bean,而其实现过程如下:

loadFactoryName方法需要两个参数,一个是通过反射得到的factoryType,一个是类加载器,但此处传入的是由两个方法分别返回的值:

getSpringFactoriesLoaderFactoryClass()
在这里插入图片描述
该方法是返回了注解类EnableAutoConfiguration,也就是我们正在探究的注解。

getBeanClassLoader()
在这里插入图片描述
该方法将当前类也就是自己加载到了JVM中。而在loadFactoryName方法中,又将EnableAutoConfiguration的类名传入了loadSpringFactories返回值Map中,当该类名存在时则返回,不存在则返回一个空集合。而当前类的加载器则作为参数传入了loadFactoryName方法
在这里插入图片描述
再查看loadSpringFactories方法:
在这里插入图片描述

在判断不为空后,通过类中的常量FACTORIES_RESOURCE_LOCATION获取到配置文件,也就是上面提到的,位于META-INF/spring.factories下的配置文件所在的路径,并将文件中的URL,通过UrlResource的方式获取到相应的资源,再将每个资源封装到了properties中,又通过Map将每个properties取出,最后并分隔成一个个的实现类,添加到接口中。那么这里就来看看spring.factories文件究竟包含了一些什么:
全局搜索后打开它,发现它位于:
在这里插入图片描述
也就是位于名为spring-boot-auotoconfigure包的下的META-INF目录下:
在这里插入图片描述
打开它:
在这里插入图片描述
发现该文件的格式都是固定的,并且从这里也能看出,该文件中记录的是常用的jar相应的url,这也就解释通了上面的方法中为什么要挨个从该文件中取出url并进行获取。那么我们再随便找几个url,看看他们的样子:
在这里插入图片描述在这里插入图片描述

发现他们的共同点都在于用@Configuration注解修饰了,而前面也分析过了,@Configuration注解的实质就是@Component,被该注解修饰的类会以Bean的方式注入到Spring容器中。

应此总结起来,自动配置的实质是通过搜索项目中的所有
META-INF/spring.factories文件,包含该配置文件的jar会被上面的loadFactoryName方法扫描到,并进行解析,通过反射的方式实例化成一个个被@Configuration修饰的配置类,最终被Spring容器加载。

@ComponentScan
从名字看它应该使用于扫描组件的,点开它:
在这里插入图片描述
看来到此处就已经到底了,并且最后一个注解@Repeatable注解告诉我们,@ComponentScan这个注解在此处是可以重复使用的,而这个注解的作用其实与Spring配置文件中的
<context:component-scan base-package=“com.maple.learn” />作用类似,可以将指定路径下带有指定注解的类自动装配到bean容器里

总结

说了这么多,写的时候自己也有点晕了,那么就用简单的话小结一下自己理解的自动装配原理:

  1. 项目通过标注了@SpringBootApplication启动应用,该注解类中又包含了:@SpringBootConfiguration、@EnableAutoConfiguration两个注解。
  2. @SpringBootConfiguratio的实际是@Component,该类作为一个配置类注入到Spring容器中
  3. @EnableAutoConfiguration是自动装配实现的核心,而它其中的@Import(AutoConfigurationImportSelector.class)则是重中之重,AutoConfigurationImportSelector类中有一个getCandidateConfigurations方法,通过调用SpringFactoriesLoader.loadFactoryNames方法扫描所有包含有META-INF/spring.factories文件的jar包,换句话说也就是只有包含了META-INF/spring.factories文件的jar包才会被扫描到并进行自动装配。
  4. spring.factories中的格式是key-value形式 ,多个value用逗号隔开,loadFactoryNames方法遍历每个key,获取其中的value,再将其一个个反射成带有@Configuration的配置类,注入到Spring容器中完成自动配置,而真正使自动配置生效的key是org.springframework.boot.autoconfigure.EnableAutoConfiguration。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/652094
推荐阅读
相关标签
  

闽ICP备14008679号