从 Spring-boot-dependencies 底层源文件可以看出,该文件通过 properties
标签对一些常用的技术框架依赖进行了统一版本号的管理,例如 activemq、spring、tomcat 等,都有于 Spring Boot 2.3.4 想匹配的版本,这也是 pom.xml 引入依赖文件不需要指定依赖文件版本号的原因。核心依赖都在父工程版本仓库中,这就是我们引入依赖时不用写版本号的原因。
需要注意的是,如果 pom.xml 文件引入依赖文件不是 spring-boot-starter-parent 管理的,那么在 pom.xml 引入依赖文件时,需要使用 <version>
标签指定依赖文件的版本号
总结:SpringBoot 依靠父项目中的版本锁定和starter机制让我们能更轻松的实现对依赖的管理。
1.1.2、spring-boot-starter-web依赖
spring-boot-starter-parent 父依赖启动器的主要作用是进行版本统一管理,那么项目运行依赖的 jar 包从何而来,又是怎样管理的呢?
查看 spring-boot-starter-web 依赖源文件,关键代码如下:
org.springframework.boot
spring-boot-starter
2.5.4
compile
org.springframework.boot
spring-boot-starter-json
2.5.4
compile
org.springframework.boot
spring-boot-starter-tomcat
2.5.4
compile
org.springframework
spring-web
5.3.9
compile
org.springframework
spring-webmvc
5.3.9
compile
从上述代码中可以发现, spring-boot-starter-web 依赖启动器的主要作用是提供 Web 开发场景所需要的底层所有依赖文件,它对 Web 开发场景所需的依赖文件进行了统一管理。
正是如此,在 pom.xml 文件中引入 spring-boot-starter-web 依赖启动器,就可以实现 web 场景开发,而不需要额外导入 Tomcat 服务器及其他 Web 依赖文件等。
Spring Boot 除了提供上述介绍的 Web 依赖启动器外,还提供了其他许多开发场景的相关依赖,可以通过 Spring Boot 官方文档进行查看。官方文档启动器
需要注意的是,Spring Boot 官方并不是针对所有场景开发的技术框架都提供了依赖启动器,例如 Mybatis、阿里巴巴的 Druid 数据源等,Spring Boot 官方就没有提供对象的依赖启动器。为了充分利用 Spring Boot 框架的优势,在 Spring Boot 官方没有整合这些技术的情况下, Mybatis 、Druid 等技术框架所在的团队主动与 Spring Boot 框架进行了整合,实现了各自的依赖启动器,例如 mybatis-spring-boot-starter、druid-spring-boot-starter 等。我们在pom.xml 文件中引入这些第三方的依赖启动器是需要配置对应的版本号。
1.1.3、依赖冲突
一般程序在运行时发生类似于 java.lang.ClassNotFoundException,Method not found: ‘……’,或者莫名其妙的异常信息,这种情况一般很大可能就是 jar包依赖冲突的问题引起的了。
一般在是A依赖C(低版本),B也依赖C(高版本)。 都是他们依赖的又是不同版本的C的时候会出现。
解决方案:
如果出现了类似于 java.lang.ClassNotFoundException,Method not found: 这些异常检查相关的依赖冲突问题,排除掉低版本的依赖,留下高版本的依赖。
我们可以使用 IDEA 插件 -> MavenHelper
1.1.4、版本锁定
我们的 SpringBoot 模块都需要继承一个父工程:spring-boot-starter-parent。在spring-bootstarter-parent的父工程spring-boot-dependencies 中对常用的依赖进行了版本锁定。这样我们在添加依赖时,很多时候都不需要添加依赖的版本号了。
我们也可以采用覆盖properties配置或者直接指定版本号的方式修改依赖的版本。
例如:
- 直接指定版本号
org.aspectj
aspectjweaver
1.7.2
- 覆盖 properties 配置
<aspectj.version>1.7.2</aspectj.version>
1.1.5、starter机制
当我们需要使用某种功能时只需要引入对应的starter即可。一个starter针对一种特定的场景,其内部引入了该场景所需的依赖。这样我们就不需要单独引入多个依赖了。
命名规律:
-
官方starter都是以
spring-boot-starter
开头后面跟上场景名称。例如:spring-boot-starterdata-jpa -
非官方starter则是以
场景名-spring-boot-starter
的格式,例如:mybatis-spring-boot-starter
@SpringBootApplication
public class SpringBootKuangApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootKuangApplication.class, args);
}
}
-
@SpringBootApplication
注解:标注这个类是一个 SpringBoot 的应用 -
SpringApplication.run()
方法:将 springboot 应用启动
我们进入@SpringBootApplication
注解
前面提到过,Spring Boot 应用的启动入口是 @SpringBootApplication
注解标注类中的 main() 方法,@SpringBootApplication 能够扫描 Spring 组件并自动配置 Spring Boot,那么它到底是如何自动配置 Spring Boot 的呢?下面通过查询 @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 {
@AliasFor(
annotation = EnableAutoConfiguration.class
)
Class<?>[] exclude() default {};
@AliasF