栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springboot入门系列之依赖管理与自动配置(1)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springboot入门系列之依赖管理与自动配置(1)

依赖管理目录:

parentstarter

自动配置目录:

引导类内嵌Tomcat自动装配总结 parent

背景:
SpringBoot关注到开发者在进行开发时,往往对依赖版本的选择具有固定的搭配格式,并且这些依赖版本的选择还不能乱搭配。比如A技术的2.0版与B技术的3.5版可以合作在一起,但是和B技术的3.7版合并使用时就有冲突。SpringBoot于是将所有的技术版本的常见使用方案都给开发者整理了出来,以后开发者使用时直接用它提供的版本方案,就不用担心冲突问题了,相当于SpringBoot做了无数个技术版本搭配的列表,这个技术搭配列表的名字叫做parent

parent特点

parent自身具有很多个版本,每个parent版本中包含有几百个其他技术的版本号,不同的parent间使用的各种技术的版本号有可能会发生变化。当开发者使用某些技术时,直接使用SpringBoot提供的parent就行了,由parent帮助开发者统一的进行各种技术的版本管理。
关注:parent定义出来以后,并不是直接使用的,仅仅给了开发者一个说明书,但是并没有实际使用,这个一定要确认清楚.

源码解析

那SpringBoot又是如何做到这一点的呢?可以查阅SpringBoot的配置源码,看到这些定义

项目中的pom.xml中继承了一个坐标


    org.springframework.boot
    spring-boot-starter-parent
    2.5.4

打开后可以查阅到其中又继承了一个坐标


    org.springframework.boot
    spring-boot-dependencies
    2.5.4

这个坐标中定义了两组信息,第一组是各式各样的依赖版本号属性,下面列出依赖版本属性的局部,可以看的出来,定义了若干个技术的依赖版本号


    5.16.3
    1.9.7
    3.19.0
    1.15
    2.8.0
    3.12.0
    1.6
    2.9.0
    1.4.200
    5.4.32.Final
    6.2.0.Final
    4.5.13
    2.12.4
    2.0.1
    1.1.4
    1.1
    9.0.48
    4.13.2

​ 第二组是各式各样的的依赖坐标信息,可以看出依赖坐标定义中没有具体的依赖版本号,而是引用了第一组信息中定义的依赖版本属性值


    
        
            org.hibernate
            hibernate-core
            ${hibernate.version}
        
        
            junit
            junit
            ${junit.version}
        
    

注意:上面的依赖坐标定义是出现在标签中的,其实是对引用坐标的依赖管理,并不是实际使用的坐标。因此当你的项目中继承了这组parent信息后,在不使用对应坐标的情况下,前面的这组定义是不会具体导入某个依赖的

注意:因为在maven中继承机会只有一次,上述继承的格式还可以切换成导入的形式进行,并且在阿里云的starter创建工程时就使用了此种形式


    
        
            org.springframework.boot
            spring-boot-dependencies
            ${spring-boot.version}
            pom
            import
        
    

总结

    开发SpringBoot程序要继承spring-boot-starter-parentspring-boot-starter-parent中定义了若干个依赖管理继承parent模块可以避免多个依赖使用相同技术时出现依赖版本冲突继承parent的形式也可以采用引入依赖的形式实现效果

思考

​ parent中定义了若干个依赖版本管理,但是也没有使用,那这个设定也就不生效啊,究竟谁在使用这些定义呢?

starter

SpringBoot关注到开发者在实际开发时,对于依赖坐标的使用往往都有一些固定的组合方式,比如使用spring-webmvc就要使用spring-web。springboot把所有的技术使用的固定搭配格式都给开发出来,叫做starter。
starter定义了使用某种技术时对于依赖的固定搭配格式,也是一种最佳解决方案,使用starter可以帮助开发者减少依赖配置

举例:
项目中的pom.xml定义了使用SpringMVC技术,但是并没有写SpringMVC的坐标,而是添加了一个名字中包含starter的依赖

    org.springframework.boot
    spring-boot-starter-web

在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
    

开发SpringMVC程序需要导入spring-webmvc的坐标和spring整合web开发的坐标,就是上面这组坐标中的最后两个了。

​ 但是我们发现除了这两个还有其他的,比如第二个,叫做spring-boot-starter-json。看名称就知道,这个是与json有关的坐标了,但是看名字发现和最后两个又不太一样,它的名字中也有starter,打开看看里面有什么?


    
        org.springframework.boot
        spring-boot-starter
        2.5.4
        compile
    
    
        org.springframework
        spring-web
        5.3.9
        compile
    
    
        com.fasterxml.jackson.core
        jackson-databind
        2.12.4
        compile
    
    
        com.fasterxml.jackson.datatype
        jackson-datatype-jdk8
        2.12.4
        compile
    
    
        com.fasterxml.jackson.datatype
        jackson-datatype-jsr310
        2.12.4
        compile
    
    
        com.fasterxml.jackson.module
        jackson-module-parameter-names
        2.12.4
        compile
    

​ 我们可以发现,这个starter中又包含了若干个坐标,其实就是使用SpringMVC开发通常都会使用到Json。SpringBoot把我们开发中使用的东西能用到的都给提前做好了。你仔细看完会发现,里面有一些你没用过的。的确会出现这种过量导入的可能性,没关系,可以通过maven中的排除依赖剔除掉一部分。

​ 到这里基本上得到了一个信息,使用starter可以帮开发者快速配置依赖关系。以前写依赖3个坐标的,现在写导入一个就搞定了,就是加速依赖配置的。

starter与parent的区别

starter是一个坐标中定了若干个坐标,以前写多个的,现在写一个,是用来减少依赖配置的书写量的

parent是定义了几百个依赖版本号,以前写依赖需要自己手工控制版本,现在由SpringBoot统一管理,这样就不存在版本冲突了,是用来减少依赖冲突的

实际开发应用方式

实际开发中如果需要用什么技术,先去找有没有这个技术对应的starter

如果有对应的starter,直接写starter,而且无需指定版本,版本由parent提供如果没有对应的starter,手写坐标即可

实际开发中如果发现坐标出现了冲突现象,确认你要使用的可行的版本号,使用手工书写的方式添加对应依赖,覆盖SpringBoot提供给我们的配置管理

方式一:直接写坐标方式二:覆盖中定义的版本号,就是下面这堆东西了,哪个冲突了覆盖哪个就OK了


    5.16.3
    1.9.7
    3.19.0
    1.15
    2.8.0
    3.12.0
    1.6
    2.9.0
    1.4.200
    5.4.32.Final
    6.2.0.Final
    4.5.13
    2.12.4
    2.0.1
    1.1.4
    1.1
    9.0.48
    4.13.2

方式二
1、查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
2、在当前项目里面重写配置
    
        5.1.43
    

温馨提示

​ SpringBoot官方给出了好多个starter的定义,方便我们使用,而且名称都是如下格式

命名规则:spring-boot-starter-技术名称

​ 所以以后见了spring-boot-starter-xxx这样的名字,这就是SpringBoot官方给出的starter定义。那非官方定义的也有吗?有的,具体命名方式到整合章节再说

总结

    开发SpringBoot程序需要导入坐标时通常导入对应的starter每个不同的starter根据功能不同,通常包含多个依赖坐标使用starter可以实现快速配置的效果,达到简化配置的目的
引导类

配置说完了,我们发现SpringBoot确实帮助我们减少了很多配置工作,下面说一下程序是如何运行的。目前程序运行的入口就是SpringBoot工程创建时自带的那个类了,带有main方法的那个类,运行这个类就可以启动SpringBoot工程的运行

@SpringBootApplication
public class Springboot0101QuickstartApplication {
    public static void main(String[] args) {
        SpringApplication.run(Springboot0101QuickstartApplication.class, args);
    }
}

​ SpringBoot本身是为了加速Spring程序的开发的,而Spring程序运行的基础是需要创建自己的Spring容器对象(IoC容器)并将所有的对象交给Spring的容器管理,也就是一个一个的Bean。那还了SpringBoot加速开发Spring程序,这个容器还在吗?这个疑问不用说,一定在。当前这个类运行后就会产生一个Spring容器对象,并且可以将这个对象保存起来,通过容器对象直接操作Bean。

@SpringBootApplication
public class Springboot0101QuickstartApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(Springboot0101QuickstartApplication.class, args);
        BookController bean = ctx.getBean(BookController.class);
        System.out.println("bean======>" + bean);
    }
}
@SpringBootApplication
//等同于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("此类所在的包")

​ 通过上述操作不难看出,其实SpringBoot程序启动还是创建了一个Spring容器对象。这个类在SpringBoot程序中是所有功能的入口,称这个类为引导类

​ 作为一个引导类最典型的特征就是当前类上方声明了一个注解@SpringBootApplication

总结

    SpringBoot工程提供引导类用来启动程序SpringBoot工程启动后创建并初始化Spring容器
内嵌Tomcat

当前我们做的SpringBoot入门案例勾选了Spirng-web的功能,并且导入了对应的starter。


    org.springframework.boot
    spring-boot-starter-web

乎SpringBoot将其定位成辅助功能,别小看这么一个辅助功能,它可是帮我们开发者又减少了好多的设置性工作。

​ 下面就围绕着这个内置的web服务器,也可以说是内置的tomcat服务器来研究几个问题

    这个服务器在什么位置定义的这个服务器是怎么运行的这个服务器如果想换怎么换?虽然这个需求很垃圾,搞得开发者会好多web服务器一样,用别人提供好的不香么?非要自己折腾

内嵌Tomcat定义位置

​ 说到定义的位置,我们就想,如果我们不开发web程序,用的着web服务器吗?肯定用不着啊。那如果这个东西被加入到你的程序中,伴随着什么技术进来的呢?肯定是web相关的功能啊,没错,就是前面导入的web相关的starter做的这件事。


    org.springframework.boot
    spring-boot-starter-web

​ 打开查看web的starter导入了哪些东西


    
        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
    

​ 第三个依赖就是这个tomcat对应的东西了,也是一个starter,再打开看看


    
        jakarta.annotation
        jakarta.annotation-api
        1.3.5
        compile
    
    
        org.apache.tomcat.embed
        tomcat-embed-core
        9.0.52
        compile
        
            
                tomcat-annotations-api
                org.apache.tomcat
            
        
    
    
        org.apache.tomcat.embed
        tomcat-embed-el
        9.0.52
        compile
    
    
        org.apache.tomcat.embed
        tomcat-embed-websocket
        9.0.52
        compile
        
            
                tomcat-annotations-api
                org.apache.tomcat
            
        
    

​这里面有一个核心的坐标,tomcat-embed-core,叫做tomcat内嵌核心。就是这个东西把tomcat功能引入到了我们的程序中。目前解决了第一个问题,找到根儿了,谁把tomcat引入到程序中的?spring-boot-starter-web中的spring-boot-starter-tomcat做的。之所以你感觉很奇妙的原因就是,这个东西是默认加入到程序中了,所以感觉很神奇,居然什么都不做,就有了web服务器对应的功能,再来说第二个问题,这个服务器是怎么运行的

内嵌Tomcat运行原理

​ Tomcat服务器是一款软件,而且是一款使用java语言开发的软件,tomcat安装目录中保存有jar,好多个jar。

​ 下面的问题来了,既然是使用java语言开发的,运行的时候肯定符合java程序运行的原理,java程序运行靠的是什么?对象呀,一切皆对象,万物皆对象。那tomcat运行起来呢?也是对象。

​ 如果是对象,那Spring容器是用来管理对象的,这个对象能不能交给Spring容器管理呢?把吗去掉,是个对象都可以交给Spring容器管理,行了,这下通了。tomcat服务器运行其实是以对象的形式在Spring容器中运行的,怪不得我们没有安装这个tomcat,是以一个对象的形式存在,保存在Spring容器中悄悄运行的。具体运行的是什么呢?其实就是上前面提到的那个tomcat内嵌核心


    
        org.apache.tomcat.embed
        tomcat-embed-core
        9.0.52
        compile
    

​ 那既然是个对象,如果把这个对象从Spring容器中去掉是不是就没有web服务器的功能呢?是这样的,通过依赖排除可以去掉这个web服务器功能


    
        org.springframework.boot
        spring-boot-starter-web
        
            
                org.springframework.boot
                spring-boot-starter-tomcat
            
        
    

​ 上面对web-starter做了一个操作,使用maven的排除依赖去掉了使用tomcat的starter。这下好了,容器中肯定没有这个对象了,重新启动程序可以观察到程序运行了,但是并没有像之前那样运行后会等着用户发请求,而是直接停掉了,就是这个原因了。

更换内嵌Tomcat

​ 那根据上面的操作我们思考是否可以换个服务器呢?必须的嘛。根据SpringBoot的工作机制,用什么技术,加入什么依赖就行了。SpringBoot提供了3款内置的服务器

tomcat(默认):apache出品,粉丝多,应用面广,负载了若干较重的组件

jetty:更轻量级,负载性能远不及tomcat

undertow:负载性能勉强跑赢tomcat

想用哪个,加个坐标就OK。前提是把tomcat排除掉,因为tomcat是默认加载的。


    
        org.springframework.boot
        spring-boot-starter-web
        
            
                org.springframework.boot
                spring-boot-starter-tomcat
            
        
    
    
        org.springframework.boot
        spring-boot-starter-jetty
    

​ 现在就已经成功替换了web服务器,核心思想就是用什么加入对应坐标就可以了。如果有starter,优先使用starter。

总结

    内嵌Tomcat服务器是SpringBoot辅助功能之一内嵌Tomcat工作原理是将Tomcat服务器作为对象运行,并将该对象交给Spring容器管理变更内嵌服务器思想是去除现有服务器,添加全新的服务器
自动装配总结

自动配好Tomcat
○ 引入Tomcat依赖。
○ 配置Tomcat


      org.springframework.boot
      spring-boot-starter-tomcat
      2.3.4.RELEASE
      compile
    

自动配好SpringMVC
○ 引入SpringMVC全套组件
○ 自动配好SpringMVC常用组件(功能)自动配好Web常见功能,如:字符编码问题
○ SpringBoot帮我们配置好了所有web开发的常见场景默认的包结构
○ 主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
○ 无需以前的包扫描配置
○ 想要改变扫描路径,@SpringBootApplication(scanbasePackages=“com.atguigu”)
■ 或者@ComponentScan 指定扫描路径

@SpringBootApplication
//等同于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.atguigu.boot")

各种配置拥有默认值
○ 默认配置最终都是映射到某个类上,如:MultipartProperties
○ 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象按需加载所有自动配置项
○ 非常多的starter
○ 引入了哪些场景这个场景的自动配置才会开启
○ SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面
○…

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/715619.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号