SpringBoot教程(二)

上一节我们已经运行了SpringBoot的HelloWorld,很简单,不用像Spring那么多配置,我们分析一下

分析

我们看一下pom.xml

1.父项目

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>


这是一个父项目,这里是spring-boot-starter-parent 所有spring-boot-starter的父项目,我们用Ctrl+鼠标左键 点击spring-boot-starter-parent,发现进入了spring-boot-starter-parent-1.5.9.RELEASE.pom,我们看到spring-boot-starter-parent还依赖一个父项目spring-boot-dependencies

我们往下看,我们再次Ctrl+鼠标左键点进去spring-boot-dependencies,则打开spring-boot-dependencies-1.5.9.RELEASE.pom


我们看到下面properties部分,定义了每一个依赖的版本,后面还有很多

其实它才是真正的SpringBoot应用所有依赖管理,所以也可以把它称为“SpringBoot的版本管理中心”,所以以后我们写SpringBoot程序是不需要导入依赖版本的(没有在这个spring-boot-dependencies中管理的则需要写版本号声明)

2. 启动器

我们接着看我们的pom.xml,发现导入了依赖spring-boot-starter-web

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

这个依赖没有版本号,我们发现与上面的父项目都是一样的前缀spring-boot-starter(SpringBoot的场景启动器)
我们再次Ctrl+鼠标左键点进去spring-boot-starter-web
我们看到它的父项目是spring-boot-starters


我们看下面,导入了一些依赖

原来它帮我们导入了web项目所需要的依赖的组件,也就是场景启动器帮我导入了web项目所需要的依赖组件,但各个组件的版本依赖父项目spring-boot-starter-parent 中的版本管理
这种类似starters(场景启动器)的做法在SpringBoot中还有很多,例如我们访问SpringBoot的官网手册
https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/
我们搜索starters,我们看到还有类似的很多starters

也就是SpringBoot将所有的功能场景都抽取出来,做成每个starters(场景启动器),我们用的时候就导入相应的starters就可以了,相关的依赖就会导入进来,版本由SpringBoot自动控制。

我们接着看一下main方法
@SpringBootApplication这个注解的意思是:标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法,来启动SpringBoot应用
我们依然Ctrl+鼠标左键点@SpringBootApplication进去,我们发现是一个组合注解,我们点击右上角的“Download Sources”因为我们没有下载SpringBootApplication源码, 所以要点击下载源码,下载完成后就是SpringBootApplication.java

下载完成后,代码有颜色提示

 我们一个一个的看一下
@SpringBootConfiguration : 标注在某个类上表示这是一个SpringBoot的配置类,而用同样的方法Ctrl + 鼠标左键点进去,我们看到底层就是@Configuration注解,与Spring的是一样的,


@Configuration :标注在某个类上表示这是一个配置类,与配置文件类似,以前开发Spring的应用需要编写很多的配置文件,很多很麻烦,我们把配置文件都替换成配置类,用注解式声明配置类,用同样的方法Ctrl + 鼠标左键点进去

我们看到其实它就是一个容器中的组件
我们看SpringBootApplication.java中的第二个注解
@EnableAutoConfiguration:开启自动配置功能

我们想想我们的工程没有配置包扫描也可以扫描、SpringMVC也启动起来了、应用也可以运行,这是怎么做到的呢?就是自动配置功能,也就是以前我们需要手动配置的,现在都是SpringBoot帮助我们自动配置了。
用同样的方法Ctrl + 鼠标左键点进去,

我们看到
@AutoConfigurationPackage:自动配置包
我们用同样的方法Ctrl + 鼠标左键点进去

我们看到它里面是
@Import(AutoConfigurationPackages.Registrar.class),而@Import就是Spring的底层注解,作用是给容器中导入一个组件,导入的组件由AutoConfigurationPackages.Registrar.class类来指定,怎么导入的呢?
我们用同样的方法Ctrl + 鼠标左键点AutoConfigurationPackages.Registrar.class进去

registerBeanDefinitions 这个方法就是注册一些Bean定义信息,通过注解标注到metadata元信息,然后getPackageName获取包名

我们在register方法上打一个断点,Debug调试一下,看它拿到的是什么包名


我们看到元信息中的SpringBootApplication是注解名,HelloWorldMainApplication是注解标注到的方法名

我们在getPackageName上右键-->Evaluate Expression...,我们计算一下包名


我们看到计算完的包名就是com.david

所以@AutoConfigurationPackage本身的含义就是将我们的主配置类HelloWorldMainApplication所在的包下面的所有的组件(包括子包下面的组件)都扫描进去
我们接着看,在@AutoConfigurationPackage注解下面还有一个注解@Import(EnableAutoConfigurationImportSelector.class)
这个就是导入组件EnableAutoConfigurationImportSelector.class,这个组件就是EnableAutoConfigurationImportSelector.class
开启自动配置导包选择器,它就是导入哪些组件的选择器
我们用同样的方法Ctrl + 鼠标左键点进去,它里面只有一个方法isEnabled

我们看它的父类AutoConfigurationImportSelector,里面有一个selectImports方法,这个方法就是告诉Spring容器到底要导入哪些组件,我们这些组件都是以String[]数组的形式返回组件的全类名,也就是将所有要导入的组件以全类名的方式返回,这些组件会被导入到容器中


我们Debug的方式运行一下,看看到底导入了哪些组件?
在public String[] selectImports(AnnotationMetadata annotationMetadata) 上设置一个断点

点击调试

运行到该处,我们可以看到元信息

按F8单步运行,直到我们看到List<String> 的对象configurations,我们看到后面都在用该对象,并且最后返回该对象的数组形式
说明它就是要返回的组件名称列表


我们再执行一次F8,让它运行到configurations,我们看到有96个组件,所以它的作用是给容器导入非常多的自动配置类(xxxAutoConfiguration),这些自动配置类的作用就是给容器中导入这个场景所需要的组件,并配置好这些组件

所以就不用手动编写配置了
那么自动配置类是怎么扫描到这些包的呢?
是在getCandidateConfigurations 获取候选的配置文件,我们Ctrl + 鼠标左键点进去


里面用到了SpringFactoriesLoader.loadFactoryNames方法,该方法传两个参数


第一个参数的值,点击进去,它就是EnableAutoConfiguration.class;



第二个参数是一个getBeanClassLoader  类加载器,我们点击进入SpringFactoriesLoader.loadFactoryNames,看一下它的作用,它用classLoader类加载器获取一个资源

然后将该资源当成一个Properties配置文件

然后从Properties中拿出factoryClassName


总结一下其实就是从"META-INF/spring.factories"中获取EnableAutoConfiguration指定的值
我们看一下导入的jar包中的这个路径的文件

我们看到这的配置就是我们导入的自动配置类

其实也就是SpringBoot启动的时候就是从"META-INF/spring.factories"中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效了,就帮我们进行自动配置工作了
我们随便看一下,我们现在是web应用,我们看一下

org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration



我们点进去,这里就是WebMvc的自动配置,@Bean就是给容器中添加一个组件,后面会详细介绍

这是给容器中添加一些filter组件

往下看,这是给容器中添加一些视图解析器

也就是我们以前自己手动的一些配置都被这些自动配置类所替换了
我们看到这就是SpringBoot用AutoConfigure对所有的大整合

都在这 spring-boot-autoconfigure-1.5.9.RELEASE.jar

猜你喜欢

转载自blog.csdn.net/dqxiaoxiao/article/details/82660047