SpringBoot源码深度剖析——@SpringBootApplication注解和ne。。。SpringBoot源码深度剖析
@SpringBootApplication注解和new SpringApplication().run()⽅法深度解密
⼀、依赖管理
本次源码剖析⽤的springboot的版本是2.2.4.RELEASE
⾸先要提出两个问题:
问题:(1)为什么导⼊dependency时不需要指定版本?
问题:(2)spring-boot-starter-parent⽗依赖启动器的主要作⽤是进⾏版本统⼀管理,那么项⽬运
⾏依赖的JAR包是从何⽽来的?
那么现在我们带着这两个问题来看代码:
问题:(1)为什么导⼊dependency时不需要指定版本?
1.spring-boot-starter-parent依赖
在项⽬的l⽂件中到spring-boot-starter-parent依赖,如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/><!-- lookup parent from repository -->
</parent>
上述代码中,将spring-boot-starter-parent依赖作为Spring Boot项⽬的统⼀⽗项⽬依赖管理,并将项⽬版本号统⼀为
2.2.4.RELEASE,该版本号根据实际开发需求是可以修改的。
使⽤“Ctrl+⿏标左键”进⼊并查看spring-boot-starter-parent底层源⽂件,发现spring-boot-starter-parent的底层有⼀个⽗依赖spring-boot-dependencies,核⼼代码具体如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${revision}</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
继续查看spring-boot-dependencies底层源⽂件,核⼼代码具体如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-build</artifactId>
<version>${revision}</version>
<relativePath>../..</relativePath>
</parent>
在此⽂件的下⽅就可以看到
<properties>
<main.basedir>${basedir}/../..</main.basedir>
<!-- Dependency versions -->
<activemq.version>5.15.11</activemq.version>
<antlr2.version>2.7.7</antlr2.version>
<appengine-sdk.version>1.9.77</appengine-sdk.version>
<artemis.version>2.10.1</artemis.version>
<aspectj.version>1.9.5</aspectj.version>
<assertj.version>3.13.2</assertj.version>
<atomikos.version>4.0.6</atomikos.version>
<awaitility.version>4.0.2</awaitility.version>
<bitronix.version>2.1.4</bitronix.version>
<byte-buddy.version>1.10.6</byte-buddy.version>
<caffeine.version>2.8.0</caffeine.version>
<cassandra-driver.version>3.7.2</cassandra-driver.version>
<classmate.version>1.5.1</classmate.version>
<commons-codec.version>1.13</commons-codec.version>
<commons-dbcp2.version>2.7.0</commons-dbcp2.version>
<commons-lang3.version>3.9</commons-lang3.version>
<commons-pool.version>1.6</commons-pool.version>
此处省略...
</properties>
从spring-boot-dependencies底层源⽂件可以看出,该⽂件通过标签对⼀些常⽤技术框架的依赖⽂件 进⾏了统⼀版本号管理,例如activemq、spring、tomcat等,都有与Spring Boot 2.2.4版本相匹配的 版本,这也是l引⼊依赖⽂件不需要标注依赖⽂件版本号的原因。
需要说明的是,如果l引⼊的依赖⽂件不是 spring-boot-starter-parent管理的,那么在 l引⼊依赖⽂件时,需要使⽤标签指定依赖⽂件的版本号。
(2)问题2: spring-boot-starter-parent⽗依赖启动器的主要作⽤是进⾏版本统⼀管理,那么项⽬运 ⾏依赖的JAR包是从何⽽来的?2.spring-boot-starter-web依赖
查看spring-boot-starter-web依赖⽂件源码,核⼼代码具体如下
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.2.2.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>2.2.2.RELEASE</version><scope>compile</scope> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.2.2.RELEASE</version>
spring mvc和boot区别<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.2.2.RELEASE</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>tomcat-embed-el</artifactId>
<groupId>at.embed</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.2.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.2.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
从上述代码可以发现,spring-boot-starter-web依赖启动器的主要作⽤是提供Web开发场景所需的底层所有依赖
正是如此,在l中引⼊spring-boot-starter-web依赖启动器时,就可以实现Web场景开发,⽽不需要额外导⼊Tomcat服务器以及其他Web依赖⽂件等。当然,这些引⼊的依赖⽂件的版本号还是由spring-boot-starter-parent⽗依赖进⾏的统⼀管理。
Spring Boot除了提供有上述介绍的Web依赖启动器外,还提供了其他许多开发场景的相关依赖,我们可以打开Spring Boot官⽅⽂档,搜索“Starters”关键字查询场景依赖启动器。
列出了Spring Boot官⽅提供的部分场景依赖启动器,这些依赖启动器适⽤于不同的场景开发,使⽤时只需要在l⽂件中导⼊对应的依赖启动器即可。
需要说明的是,Spring Boot官⽅并不是针对所有场景开发的技术框架都提供了场景启动器,例如数据库操作框架MyBatis、阿⾥巴巴的Druid数据源等,Spring Boot官⽅就没有提供对应的依赖启动器。为
了充分利⽤Spring Boot框架的优势,在Spring Boot官⽅没有整合这些技术框架的情况下,MyBatis、Druid等技术框架所在的开发团队主动与Spring Boot框架进⾏了整合,实现了各⾃的依赖启动器,例如mybatis-spring-boot-starter、druid-spring-boot-starter等。我们在l⽂件中引⼊这些第三⽅的依赖启动器时,切记要配置对应的版本号。
⼆、⾃动装配(启动流程)
问题:Spring Boot到底是如何进⾏⾃动配置的,都把哪些组件进⾏了⾃动配置?
Spring Boot应⽤的启动⼊⼝是@SpringBootApplication注解标注类中的main()⽅法,@SpringBootApplication能够扫描Spring组件并⾃动配置Spring Boot。
下⾯,查看@SpringBootApplication内部源码进⾏分析 ,核⼼代码具体如下
三、@SpringBootApplication注解的底层实现
@SpringBootApplication
public class SpringBootMytestApplication {
public static void main(String[] args){
SpringApplication.run(SpringBootMytestApplication.class, args);
}
}
@Target(ElementType.TYPE)// 注解的适⽤范围,Type表⽰注解可以描述在类、接⼝、注解或枚举中
@Retention(RetentionPolicy.RUNTIME)// 表⽰注解的⽣命周期,Runtime运⾏时
@Documented // 表⽰注解可以记录在javadoc中
@Inherited // 表⽰可以被⼦类继承该注解
//--------------------------------------------------------
@SpringBootConfiguration // 标明该类为配置类
@EnableAutoConfiguration // 启动⾃动配置功能
@ComponentScan(excludeFilters ={ @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)})
public @interface SpringBootApplication {
从上述源码可以看出,@SpringBootApplication注解是⼀个组合注解,前⾯ 4 个是注解的元数据信息, 我们主要看后⾯ 3 个注解:
@SpringBootConfifiguration、@EnableAutoConfifiguration、@ComponentScan三个核⼼注解,关于这三个核⼼注解的相关说明具体如下:
1.@SpringBootConfifiguration注解
@SpringBootConfifiguration注解表⽰Spring Boot配置类。查看@SpringBootConfifiguration注解源码,核⼼代码具体如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
从上述源码可以看出,@SpringBootConfifiguration注解内部有⼀个核⼼注解@Confifiguration,该注解是Spring框架提供的,表⽰当前类为⼀个配置类(XML配置⽂件的注解表现形式),并可以被组件扫描器扫描。由此可见,@SpringBootConfifiguration注解的作⽤与@Confifiguration注解相同,都是标识⼀个可以被组件扫描器扫描的配置类,只不过@SpringBootConfifiguration是被Spring Boot 进⾏了重新封装命名⽽已。
2.@EnableAutoConfifiguration注解
@EnableAutoConfifiguration注解表⽰开启⾃动配置功能,该注解是Spring Boot框架最重要的注解,也是实现⾃动化配置的注解。同样,查看该注解内部查看源码信息,核⼼代码具体如下:
可以发现它是⼀个组合注解,Spring 中有很多以Enable开头的注解,其作⽤就是借助@Import来收集并注册特定场景相关的bean,并加载到IoC容器。@EnableAutoConfifiguration就是借助@Import来收集所有符合⾃动配置条件的bean定义,并加载到IoC容器。 下⾯,对这两个核⼼注解分别讲解:
(1)@AutoConfifigurationPackage注解
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论