1、依赖管理
父项目做依赖管理
为什么我们仅仅引入了一个父项目然后添加了一个依赖,所有有关的jar就都被导入进来了呢?
每个springboot工程都包含这么个parent
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
</parent>
我们都知道父项目我们一般使用它做依赖管理,只要子项目继承他那么就不需要版本号了。
使用idea进入到该父项目,发现该父项目还有一个父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
这个项目中的propertes标签中几乎声明了所有开发中常用的依赖的版本号,所以我们无需引入版本号。这个是springboot的自动版本仲裁机制,例如我们的mysql,我们只需要这样引入
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
此时根据自动版本仲裁机制,就会使用父项目的版本,也就是父项目中的properties中规定的版本
可以修改默认版本号
1、查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
2、在当前项目里面重写配置
<properties>
<mysql.version>5.1.43</mysql.version>
</properties>
这样修改其实就是利用了maven的依赖就近原则
开发期间的场景启动器
我们后面会见到很多spring-boot-starter-*
这样的依赖名,这写都是一些场景的启动器,当我导入了这个场景的启动器,那么这个场景中所需的依赖根据maven的依赖传递的特性,我们就得到了不同场景对应的jar了
springboot所有支持的场景,点击查看
我们也可以自己创建场景启动器,官方建议我们自定义的场景启动器的不应该以spring-boot-starter-*
这样的形式命名,而是以*-spring-boot-starter
这样的形式进行命名这样可以区分出来官方的场景启动器和自定义的场景启动器
所有场景启动器的最底层都会依赖以这个这样的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.3.4.RELEASE</version>
<scope>compile</scope>
</dependency>
这个就是springboot自动配置的核心依赖
总结
引入依赖默认可以不写版本号,但是前提是springboot提供的版本是我们想要使用的版本,并且springboot提供了我们所需的依赖
2、自动配置
- 自动配置Tomcat
- 自动配置springMVC
- 自动配置号Web常见功能,如:字符编码问题
- 默认的包结构
- 默认配置拥有默认值
- 按需加载所有自动配置项
- …等等
自动配置Tomcat
引入了Tomcat的依赖
配置Tomcat
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.43</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>tomcat-annotations-api</artifactId>
<groupId>org.apache.tomcat</groupId>
</exclusion>
</exclusions>
</dependency>
而这个依赖并不是我们直接引入的,而是我们引入web场景启动器的依赖,web场景启动器中就包含了tomcat的这个依赖
自动配置好springMVC
引入SpringMVC全套组件
自动配好了SpringMVC常用组件
我们可以查看
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
//返回ioc容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
//通过该方法获取ioc容器中存放的组件的名称数组
String[] beanDefinitionNames = run.getBeanDefinitionNames();
//遍历该数组
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
}
我们可以看到像原先我们使用SpringMVC时需要配置的控制器dispatcherServlet
这就是为什么我们不用自己配置
自动配置好web常见的功能,如字符编码问题
SpringBoot帮我们配置好了所有web的常见开发场景,像我们原先如过使用SpringMVC给页面响应一个中文字符,我们需要配置字符控制器,但是我们使用springboot就不用配置,因为他已经帮我们自动配置好了
@RestController
public class HelloController {
@RequestMapping("/hello")
public String handle01(){
return "Hello,SpringBoot2,中文成功显示";
}
}
默认的包结构
向我们使用的SpringMVC时使用注解配置,但是我们并灭有配置要扫描的包,但是我们的注解也被识别了,这就是因为springboot有一个默认的扫描方式,它会帮我们实现扫描注解的这个功能
这里是官方文档的说明
这个扫描的默认规则就是:主程序及其下面的所有子包里面的组件都会被默认扫描
官方文档图示如下
这样我们只要遵守这个约定,那么我们就不用配置包扫描了
那么如果我们偏偏不按照这个约定进行创建需要被扫描的类时应当如何?
第一种解决方式:
只需要进行一些小小的配置即可
在我们表明主程序入口的注解@SpringBootApplication
中有一个属性,就是用于配置需要扫描的包
我们只需要配置上我们想要扫描的包即可
第二种解决方式
可以使用包扫描注解@ComponentScan()
配置即可,该注解后面会详细介绍如何使用
因为@SpringBootApplication
不能和@ComponentScan()
同时使用,因为@SpringBootApplication
中包含了@ComponentScan()
注解,但是如果我们想使用@ComponentScan()
注解的话,可以不写@SpringBootApplication
,而是写如下三个注解
这时因为@SpringBootApplication
是一个合成注解,@SpringBootApplication
顶这三个注解,使用这三个注解也可以替代@SpringBootApplication
各种配置都有默认值
比如tomcat默认端口8080
这些默认配置最终都是映射到某个类上
配置文件的值最终会绑定到每个类上,这个类在容器中创建对象
按需加载所有自动配置项
有很多的场景
引入了哪个场景,那么这个场景的自动配置才会开启
SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面