Spring Boot 手摸手系列-hello word(二)要点分析

/ 2020-08-01 / 246人浏览 / 0人评论

上一篇文章 Spring Boot 手摸手系列-hello word 介绍了如何使用springboot,springboot 如何打包成可执行jar。但是我们只知道如何去使用,springboot 为什么这么简洁方便呢。下面分为几点简单来介绍下:

1、关于pom 文件中的parent-spring-boot-starter-parent

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.2.2.RELEASE</version>
	<relativePath /> <!-- lookup parent from repository -->
</parent>
这是项目中的父项目依赖,它为我们做了什么呢?
点进去一看,发现它也有一个父项目依赖
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.2.2.RELEASE</version>
    <relativePath>../../spring-boot-dependencies</relativePath>
</parent>

这个spring-boot-dependencies 中为我们声明好了依赖匹配的版本;减少了很多繁琐工作。所以 spring-boot-dependencies 就是springboot的应用依赖管理,也是版本权威。

2、关于pom文件中的 dependency spring-boot-starter-web
直接从pom文件中点进去会发现一个有趣的东西;

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starters</artifactId>
    <version>2.2.2.RELEASE</version>
</parent>

spring-boot-starters 是springboot 的场景启动器;然后他的父项目依赖是spring-boot-parent

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-parent</artifactId>
    <version>2.2.2.RELEASE</version>
    <relativePath>../spring-boot-parent</relativePath>
</parent>

spring-boot-parent 点进去一看,父项目依赖竟然是spring-boot-dependencies;兜兜转转又一圈啊

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.2.2.RELEASE</version>
    <relativePath>../spring-boot-dependencies</relativePath>
</parent>

spring-boot-starters 是 springboot 场景启动器;
spring-boot-starter-web 必然就是 springboot web 这个场景的启动器,
看其pom dependency,发现它帮我们引入了web所需要的一些依赖;这样我们自己项目中只要引入 spring-boot-starter-web 的依赖 ,其实我们已经将web 相关依赖都解决了。是不是实在是太方便了啊,同样的,我们可以直接依赖springboot的其他场景启动器就可以直接使用了。
数据库操作可以直接使用 spring-boot-starter-data-jpa
activemq 可以直接使用 spring-boot-starter-activemq
....

3、springboot 主程序启动类 StartApplication
@SpringBootApplication 看下源码就发现它是一个组合注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

@SpringBootConfiguration 看源码底层就是一个 @Configuration,可以直接理解为表示springboot配置类的注解

@Configuration 表示配置类的一个注解;(配置类相当之前的配置文件),但是配置类其实也是一个@Component(组件),各自代表的含义不同。

@EnableAutoConfiguration 表示开启自动配置功能。

它干了啥事呢?它就是告诉springboot,开启自动配置功能,然后以前很多需要我们手动配置的活,都给它给抢干掉了,所以你就轻松了,啥也不干。
关键它咋实现的呢?

看它源码其实他底层就是一个 @AutoConfigurationPackage;
@AutoConfigurationPackage 这个是啥玩意呢?
@AutoConfigurationPackage 底层是@Import(AutoConfigurationPackages.Registrar.class),它干的事其实就是导入AutoConfigurationPackages.Registrar.class 指定的组件到spring容器中;如果你debug走一遭,你就会发现,导入的组件其实就是 @SpringBootApplication 注解指定的主程序类所在包以及子包下的所有组件;(简单一句话概括就是 @AutoConfigurationPackage 将 主程序类所在包以及子包下的所有组件扫描到spring容器中)

@Import(xxx.class) 功能就是给容器中导入 xxx.class 指定的组件。

那么 @EnableAutoConfiguration 下还有一个注解 @Import(AutoConfigurationImportSelector.class)就比较容易理解了,我们只要看看 AutoConfigurationImportSelector.class 的源码。

AutoConfigurationImportSelector 其实是表示需要导入哪些自动配置类(自动配置类就是给容器导入该场景下所需的组件,并配置好这些组件)的一个选择器,它返回了需要导入的组件全类名。
它是从 spring-boot-autoconfigur jar 包下的 META-INF/spring.factories 中获取自动配置类列表。后续使用的 javaEE 使用相关的配置,其实都在里面,所以说springboot 是 javaEE 的一个大整合,是javaEE的整体的解决方案

 

全部评论