SpringBoot深入分析运行原理与功能实现
作者:Binaire-沐辰 发布时间:2022-01-03 14:48:43
前言
我们从以下几个方面研究:
SpringBoot的启动依赖
启动器starter有什么作用
启动引导类是怎么运行的
内置的tomcat服务器原理
pom.xml文件分析
我们应用配置第一个就是依赖,这个依赖的作用到底是什么我们仔细来分析一下。
项目中的pom.xml中继承了一个坐标
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
注意:这里parent的坐标被工程继承了,相当于这是一个父类,我们创建的工程是一个子类,用到了父类的东西。
打开spring-boot-starter-parent
之后,发现他又继承了一个坐标。
继续打开spring-boot-dependencies
之后,发现该文件中主要定义了两组信息,分别是各种依赖的版本号和所有依赖的坐标信息,并对声明的版本号做了一个引用。我们打开发现这里有两千多行,所有能配置的版本基本都包含了。
由于Spring Boot工程使用到了maven的聚合工程,所以这里我们可以认为spring-boot-dependencies
就是父工程,子工程就是我们自己的项目。当我们子工程中使用<parent>
继承父类之后,所有的版本就都由父类决定了。
可以看到子工程当中我们没有声明版本号,是因为所有的版本都由父类决定,这样做的好处是什么:解决了版本冲突。不同模块、不同功能之间使用的版本是不一样的,因此spring boot就为我们将所有的版本统一化了。
启动器starter
SpringBoot官方给出了好多个starter的定义,方便我们使用,而且名称都是如下格式
命名规则: spring-boot-starter-技术名称
starter定义了使用某种技术时对于依赖的固定搭配格式,也是一种最佳解决方案,使用starter可以帮助开发者减少依赖配置
项目中的pom.xml定义了使用springMVC技术,但是并没有写SpringMVC的坐标,而是添加了一个名字中包含starter的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
在spring-boot-starter-web中又定义了若干个具体依赖的坐标
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>2.7.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.7.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.22</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.22</version>
<scope>compile</scope>
</dependency>
</dependencies>
然后你可以继续打开任意一个依赖,发现里面又会包含一些依赖。
我们可以发现,这个starter中又包含了若干个坐标,其实就是使用SpringMVC开发通常都会使用到Json,使用json又离不开这里面定义的这些坐标,看来还真是方便,SpringBoot把我们开发中使用的东西能用到的都给提前做好了。你仔细看完会发现,里面有一些你没用过的。的确会出现这种过量导入的可能性,没关系,可以通过maven中的排除依赖剔除掉一部分。不过你不管它也没事,大不了就是过量导入呗。
总结:
使用starter可以帮开发者快速配置依赖关系。以前写依赖3个坐标的,现在写导入一个就搞定了,就是加速依赖配置的。
启动引导类
目前程序运行的入口就是SpringBoot工程创建时自带的那个类了,带有main方法的那个类,运行这个类就可以启动springBoot工程的运行
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Spring Boot本身就是为了加速Spring程序而开发的,而Spring程序运行的基础是需要创建自己的Spring容器对象,并将所有的对象管理在容器里面,这时候你可能会疑惑,Spring boot加速了Spring程序,那spring boot中有没有容器呢,或者说这个容器还存在吗?答案是存在,我们可以修改上面的代码来验证一下。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
Application bean = context.getBean(Application.class);
System.out.println(bean);
}
}
这里的ConfigurableApplicationContext继承了ApplicationContext,说明他就是一个容器,拿到容器之后再通过getBean()来拿到bean,打印在控制台。
可以看到控制台打印出来了对应的地址,说明它就是c从容器中拿到的一个对象,说明spring boot中存在一个容器,而SpringApplication.run(Application.class, args);
就是运行Spring Boot容器,
@SpringBootApplication注解
接下来我们看一下@SpringBootApplication
注解
根据箭头打开注解可以看到有Spring Boot配置以及自动配置,自动配置包等等,因此当程序加了@SpringBootApplication
注解,他就会扫描这个类所在包下和子包下面的所有类。并且他还是spring boot的配置类,所以spring的一些配置文件就不用写了,配置类自动搞定了。
总结一下:这个启动引导类,创建了一个容器并将该容器运行起来,做了一个配置类,里面有一些自动配置的东西,然后我们创建的对象就可以放在引导类的包以及子包中,就可以扫描到了。
内置的服务器
我们在创建spring boot项目时,会勾选需要的依赖,然后导入对应的starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
内置的tomcat服务器来研究几个问题
这个服务器在什么位置定义的
这个服务器是怎么运行的
这个服务器如果想换怎么换
内嵌Tomcat定义位置
说到定义的位置,我们可以通过两种方式来查看:
第一种
第二种
tomcat运行原理
tomcat本身就是一个Java项目,那么可不可以将tomcat中的一些东西直接放回项目中,让他变成一个Java代码?
当然可以,这里spring boot将tomcat以jar包的形式放到spring容器中让他变成一种对象,然后运行这个对象,把我们的项目启动起来,这就是它能够启动并且运行的原理。
修改服务器
如果我们不想用他提供的版本能不能修改呢?可以,我们可以通过<exclusions>
标签来排除提供的版本,或者内置服务器,然后在再重新添加依赖来达到修改服务器版本或者更换服务器的目的。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
当添加<exclusions>
标签之后,就把内置的tomcat的服务器排除了,这时候你在启动项目,在控制台就不会看到tomcat相关的信息了,并且网页也无法访问了。
添加服务器
这时候你再添加你想要的使用的服务器,只需添加对应的坐标即可
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
同样在控制台就会看到服务器相关的信息了,并且网页也可以正常访问了。不过这样就显得有点多此一举了,好好的东西不用,非要自己搞这些,所以还是建议使用内置的服务器。
更换内嵌服务器
那我们是否可以换个服务器呢?必须的嘛。根据SpringBoot的工作机制,用什么技术,加入什么依赖就行了。SpringBoot提供了3款内置的服务器
tomcat(默认): apache出品,粉丝多,应用面广,负载了若干较重的组件
jetty:更轻量级,负载性能远不及tomcat
undertow:负载性能勉强跑赢tomcatI
想用哪个,加个坐标就OK。前提是把tomcat排除掉,因为tomcat是默认加载的。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
现在就已经成功替换了web服务器,它的核心思想就是加入对应的坐标就可以了。
来源:https://binaire.blog.csdn.net/article/details/126740690


猜你喜欢
- 前言在上篇文章(Android实现圆弧滑动效果之ArcSlidingHelper篇)中,我们把圆弧滑动手势处理好了,那么这篇文章我们就来自定
- 我们知道HashMap集合是允许存放null值的hashMap是根据key的hashCode来寻找存放位置的,那当key为null时, 怎么
- 赋值运算符也有和算数操作符所结合的用法之前附录中有提及,用法是:比如要将x加上4,然后再赋值给x,就可以写成x+=4. public cla
- main.xml:<?xml version="1.0" encoding="utf-8"?&
- 本文实例讲述了Java字符流与字节流区别与用法。分享给大家供大家参考,具体如下:字节流与字符流主要的区别是他们的的处理方式流分类:1.Jav
- 前言在之前的Spring Boot基础教程系列中,已经通过《Spring Boot中使用@Async实现异步调用》一文介绍过如何使用@Asy
- 身为一名开发人员,大家都知道,我们经常会在项目中大量的编写许多重复的代码,比如说public Entity find(String id);
- 在开发过程中.数组和集合的处理是最让我们担心.一般会用for or foreach 来处理一些操作.这里介绍一些常用的集合跟数组的操作函数.
- 为了演示光照效果,在前面学习过的内容基础上我们首先创建一个立方体,同时为了看起来直观一些,这个立方体每个面采用中心为白色,周围红色的渐变方案
- lombok插件使用引入依赖,在项目中使用Lombok可以减少很多重复代码的书写。比如说getter/setter/toString等方法的
- 最近有小伙伴告诉我,在循环的判断条件只会计算一次,本金鱼不相信,于是就做了测试,本文记录我做的测试。先来写一个简单的代码, 就一个循环,循环
- HttpResponse 讲解HttpServletResponse概述:在创建Servlet时会覆盖service()方法,或doGet(
- 数据类型转换就是将数据(变量、表达式的结果)从一种类型转换到另一种类型。例如,为了保存小数你可以将int类型的变量转换为double类型。数
- mybatis if传入字符串数字踩坑前台页面内容,注意这里的类型为字符串类型的数字<li>  
- 介绍: Mybatis-Plus(简称MP)
- 最近有学生做毕业设计,想使用悬浮窗这种效果,其实很简单,我们可以通过系统服务WindowManager来实现此功能,本章我们来试验一下在当前
- 一、简介项目开发中存在系统之间互调问题,又不想用dubbo,这里提供几种springboot方案:1、使用Feign进行消费(推荐)2、使用
- java 读取网页内容的实例详解import java.io.BufferedReader; import java.io.IOExcept
- 公司在使用定时任务的时候,使用的是spring scheduled。代码如下:@EnableSchedulingpublic class T
- 这篇文章主要介绍了Springboot配置文件内容加密代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,