04-SpringBoot自动配置原理

springboot的自动配置原理

1、springboot的特点

1、1 依赖管理

  • springboot项目中的pom文件中继承一个父项目作为依赖管理

    <!--parent标签,表示是一个父项目,这个maven项目继承该项目-->
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>2.2.5.RELEASE</version>
    		<!--下面这个标签表示的是一个远程的父项目-->
    		<relativePath/> <!-- lookup parent from repository -->
    	</parent>
    
    当子项目继承了这个父项目spring-boot-starter-parent,在以后写依赖,就不需要版本号了
    主要功能就是:声明了开发中使用的几乎所有的依赖版本,版本仲裁
    

    Ctrl+点击这个父项目,可以看到spring-boot-starter-parent项目还有一个父项目spring-boot-dependencies

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

    ​ 当我们再次点进spring-boot-dependencies项目中的pom文件时,可以看到其中有个标签,其中声明了当前我们开发时所有需要的依赖的版本号(包括很多,切面的AspectJ、数据源的、Spring相关的等等),这些依赖的版本都是不排斥可互通使用的,这样我们就不会出现添加不同依赖,由于选择这些依赖版本不匹配而导致的问题了,这些父项目都帮我们选择好了。而且其中也声明名了所有依赖版本的依赖,所以我们第一次创建springboot项目时,要导入很多的依赖。

    ​ 当我们不想要父项目中仲裁的版本号时,如父项目中的properties标签中定义的mysql驱动的版本的标签是<mysql.version>版本号<mysql.version>,我们可以在当前项目的pom文件中编写一个properties标签,把<mysql.version>版本号<mysql.version>中的版本号改成我们想要的,然后填写mysql驱动依赖就行了。这也相当于是重写配置。

  • 开发时导入starter场景启动器

    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    
    starters:
    	是一组依赖的的集合描述,比如说我们开发web应用,可以称之为web场景下开发,只需要引入一个Web的starter,就能吧和web开发这个场景可能所用到的所有常规依赖jar包全部引入进来了。
    	而springboot中的starter是以spring-boot-starter-*命名的,这个*代表的内容就是我们开发中所见到的一些开发场景,具体的springboot能满足的场景可以到官方文档中的Using Spring Boot->Starters中查看,有spring-boot-starter-aop的、spring-boot-starter-amqp(高级消息队例)、spring-boot-starter-cache(缓存的)等等
    	实在满足不了的也可以自定义starters,一般我们见到的*-spring-boot-*的就是别人创建的starter,是第三方为我们提供的简化开发的场景启动器,非springboot官方的starter不能以spring-boot开头
    	我们在项目的pom文件中点击右键,使用工具,选择Diagrams->Show Dependencies查看依赖树状图,如下
    

04-SpringBoot自动配置原理

从图中我们可以看到,web开发场景引入了json、tomcat和validation的开发场景,这些场景又引入了大量的jar包,而其中最主要的最基本的依赖还是spring-boot-starter,所有的spring-boot-starter-*的场景启动器都有这个依赖,这个是最基本最底层的依赖。
	<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>2.2.5.RELEASE</version>
      <scope>compile</scope>
    </dependency>
  • 无需关注版本号,自动版本仲裁

    但是引入非仲裁的jar包需要写版本号
    
  • 可以自己修改版本号

1、2自动配置特性

  • 自动配置好Tomcat

    1、引入Tomcat依赖
    我们引入web的场景启动器:
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    Ctrl+spring-boot-starter-web点击进去,可以看到其中有:
    	<dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-tomcat</artifactId>
          <version>2.2.5.RELEASE</version>
          <scope>compile</scope>
        </dependency>
    2、配置好Tomcat
    
  • 自动配置好SpringMVC

    1、由前面的web启动器,其引入了SpringMVC的全套组件
    2、自动配置好SpringMVC常用组件功能
    
  • 自动配置好Web开发常见功能,如:字符编码问题的过滤器、DispatcherServlet、ViewResolver视图解析器等。

    1、在主程序类中中修改一下,如下:
        
    @SpringBootApplication//表示这是一个springboot应用
    public class ASpringbootHelloworldApplication {
    
    	//SpringApplication
    	public static void main(String[] args) {
    
    		//1、返回一个IOC容器
    		ConfigurableApplicationContext run  = SpringApplication.run(ASpringbootHelloworldApplication.class, args);
    
    		//2、查看容器中帮我们创建的组件(对象)的名字
    		String[] names = run.getBeanDefinitionNames();
    		for (String name:
    			 names) {
    			System.out.println(name);
    		}
    	}
    
    }
    输出了很多组件的名称
    1)、可以看到输出到控制台中有一个:dispatcherServlet组件,自动帮我们创建了*调度器,但我们没有声明配置
    2)、还有一个字符编码的过滤器:characterEncodingFilter组件,自动创建。
    3)、还有很多的视图解析器
    4)、文件上传的视图解析器:multipartResolver
    ...
    这些组件都帮我们配置好了,由IOC容器自动生成。
    //springboot帮我们配置好了所有web开发的常见问题
    
  • 默认的包结构

    1、主程序类所在的包及其下面的子包里面的所有组件都会被默认扫描进来,这是一种约定、规则。我们不能乱放组件类。
    2、无需像以前一样声明组件时指定要扫描的包,只需要添加注解就行了,注解开发
    3、要想改变扫描路径,可以使用@SpringBootApplication(scanBasePackages = "com.studymyself")
      或者@ComponentScan指定扫描路径
        
        @SpringBootApplication	
        等同于这三个:
        @SpringBootConfiguration
        @EnableAutoConfiguration
        @ComponentScan
        我们可以去掉整合的@SpringBootApplication	,主程序类上面放这三个,
        然后在 @ComponentScan("扫描的路径")中指定扫描路径
    
  • 各种配置都有默认值

    1、默认配置最终都是映射到配置文件中的,如application.properties
    2、配置文件中的值最终绑定到每个类中,最后到每个组件中。
    
  • 按需加载所有的自动配置项

    1、我们当前导入的是web开发场景,springboot就帮我们自动配置了该场景所需的所有配置,还有很多的starter可以根据需求导入,让springboot帮你配置
    2、自动配置某个场景需要我们引入这个场景的启动器才能配置
    3、springboot自动配置的功能在这个基本启动器中
    	 <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter</artifactId>
          <version>2.2.5.RELEASE</version>
          <scope>compile</scope>
        </dependency>
    4、点击进这个启动器,和自动配置相关的功能就是这个包:
    	<dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-autoconfigure</artifactId>
          <version>2.2.5.RELEASE</version>
          <scope>compile</scope>
        </dependency>
    5、从依赖中找到这个jar包点开这个项目spring->boot->autoconfigure,autoconfigure目录中的各个包就是对所有场景的自动配置代码,如果我们没有引入相关场景启动器依赖,点开代码有些是爆红的
    

04-SpringBoot自动配置原理

上一篇:SpringBoot系列之starter原理


下一篇:1.Starting with Spring Initialize pom.xml文件初始化