5 分钟快速理解 Spring Boot

简介: 前言Spring 是 Java 开发人员接触最多的框架,包括我在内的很多小伙伴只是对 Spring 进行简单使用,为了深入了解 Spring,我在 2020 年 6 月底的时候开始了 Spring 探索之路,并开设了《重学 Spring》专栏,到目前为止已经更新了 51 篇,内容涵盖了 Spring IOC、Spring AOP、Spring MVC 等内容,详细的介绍了 Spring 的核心特性与底层原理,也希望在读的小伙伴能更上一层楼。


前言


Spring 是 Java 开发人员接触最多的框架,包括我在内的很多小伙伴只是对 Spring 进行简单使用,为了深入了解 Spring,我在 2020 年 6 月底的时候开始了 Spring 探索之路,并开设了《重学 Spring》专栏,到目前为止已经更新了 51 篇,内容涵盖了 Spring IOC、Spring AOP、Spring MVC 等内容,详细的介绍了 Spring 的核心特性与底层原理,也希望在读的小伙伴能更上一层楼。


Spring Boot 是为了进一步简化 Spring 开发提出的一个框架,很多特性都基于 Spring Framework,目前新入门的同学应该已经直接跳过 Spring Framework 直接使用 Spring Boot 了,这也说明了 Spring Boot 的火热程度。


最近半个月没有更新博客我也是在梳理 Spring Boot 的内容,目前我已经整理了近 20 个课题,计划在未来的 3 个月内更新完毕。本篇是 Spring Boot 的开篇,主要是带着大家重新认识一下 Spring Boot,达到鸟瞰全景的目的,后面会逐步深入。


概述


用一句话实在难以概述 Spring Boot,如果一定要为它下一个定义的话,那么 Spring Boot 可以被理解为是一个用来简化 Spring 应用创建、开发和运行的框架。


Spring Boot 第一个版本发布于 2014 年 4 月,目前最新的版本是 2.x,对 JDK 版本的要求是 1.8 及以上,对 Maven 版本的要求是 3.3 及以上,本文示例中使用的 Spring Boot 版本号是 2.2.7.RELEASE 。


Spring Boot 是如何简化应用创建的?


关于简化应用创建,最近几年刚学编程的同学可能并没有太大的感触,5 年前的 Spring 项目搭建可真是一个痛苦的过程。


最初的 Java 项目如果依赖了第三方的库,是直接将 jar 包添加到类路径中的,每次创建一个项目都需要重复这个过程,如果依赖的第三方库比较少还好,如果依赖的比较多,依赖的 jar 包发生了相互依赖,并且版本还不同,那可就头痛了。


以 Spring 为例,如果我们引入了 spring-webmvc 模块,我们还要紧跟着把 spring-webmvc 模块依赖的 spring-bean 模块加入到类路径,由于 spring-bean 模块依赖了 spring-core 模块,还要添加 spring-core 添加到类路径,而我们只是想用 spring-webmvc 模块而已。


好在后来出现了一些依赖管理工具,例如 maven、gradle、ant,由于目前在 Java 开发中 maven 用的比较多,后面我们就拿 maven 举例了。尽管有了 maven 管理依赖,但是由于 Spring 是一个 bean 的容器,因此还需要将 bean 的元信息进行配置,最初的 Spring 使用业界最为流行的 xml 配置 bean,后来 JDK 5 注解出现后才逐渐将配置迁移到注解,曾经一度出现了 xml 和注解混用的场景。


基于 Spring Framework 的 Spring MVC 项目搭建

由于 Spring 主要应用于 Web 开发,下面看下 Spring Boot 出现前是如何搭建 Spring MVC 项目的。


Spring MVC 项目需要引入 spring-webmvc 模块的依赖,因此首先要找的就是 spring-webmvc 的坐标,对于新手来说一般就是在网上找一些 Spring MVC 的入门文章,直接复制 spring-webmvc 的坐标了,此外就是在 maven 仓库 中根据关键字搜索。不管怎样找坐标吧,最终我们配置最简单的 pom.xml 内容如下。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.zzuhkp</groupId>
    <artifactId>mvc-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>


除了引入 spring-webmvc 的依赖,由于我们还可能会使用到一些 Servlet 规范中的一些类,我们还引入了 Servlet 的依赖。而依赖引入只是万里长征的第一步,由于 Java Web 开发中的接口都是 Servlet 提供的,我们还需要配置 spring-webmvc 模块提供的 Servlet 接口的实现 DispatcherServlet。这又是什么东西?当时作为新手我的也是一脸懵逼,配置时我还得找到这个类的全限定名,这对于新手来说也太不友好了,又是一波复制粘贴。最终配置出来的 web.xml 文件内容如下。


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
          http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>


到这里就完了吗?显然不是,我们还没有为 Spring 配置 bean。对于 Spring MVC 来说,我们需要把 Spring 的配置文件放在 /WEB-INF/${servlet-name}-servlet.xml 中,其中 ${servlet-name} 为 Servelt 的名称,我们为 DispatcherServlet 取的名字是 dispatcher,因此我们需要创建 /WEB-INF/dispatcher-servlet.xml 作为配置文件。这对新手又是一个挑战,还得记住命名规范,那能不能自己指定配置文件位置呢?可以,配置一个 Servlet 的初始化参数 configurationLocation 指定配置文件,好吧,还得记住参数名称。真是令人崩溃,最后看下配置文件的内容吧。


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/page"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <context:component-scan base-package="com.zzuhkp.mvc"/>
</beans>


最初的 Java Web 开发可没有前后端分离,为了根据视图名称查找到对应的 JSP 文件,我们配置一个 InternalResourceViewResolver 类型的视图解析器 bean,这是 Spring MVC 特有的一个 bean,又是一个新概念,视图解析器又是什么?此外,我们为了启用注解支持,我们添加了 context:compent-scan 标签指定了要 Spring 要扫描的包。bean 的配置还好,最要名的是 xml 配置的命名空间,就是最上面那一坨,除了复制粘贴谁能自己写出来呢?


写到这里,我已经近乎崩溃了,简直又经历了一次那段痛苦的历史。来个 Controller 测试下请求是否正常。


@Controller
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "/hello";
    }
}


Controller 方法 String 类型的返回值将作为视图名,这里我们指定的是 /hello,也就是说有一个 /hello 对应的 jsp 文件,当请求 /hello 时我们将这个文件的内容返回给前端,结合我们前面配置的 InternalResourceViewResolver,它的位置应该是 /WEB-INF/page/hello.jsp,我们定义的文件内容如下。


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>hello</title>
</head>
<body>
Hello,Spring MVC
</body>
</html>


最后整个项目结构如下。


.
├── pom.xml
└── src
    └── main
        ├── java
        │   └── com
        │       └── zzuhkp
        │           └── mvc
        │               └── HelloController.java
        └── webapp
            ├── WEB-INF
            │   ├── dispatcher-servlet.xml
            │   └── web.xml
            └── page
                └── hello.jsp


将项目发布到 Tomcat,请求 /hello,结果如下。


image.png


至此,终于将一个最简单的 Spring MVC 项目搭建完成。


基于 Spring Boot 的 Spring MVC 项目搭建

总结基于 Spring Framework 的 Spring MVC 项目搭建有哪些问题呢?


首先概念过多,新人需要关注 spring-webmvc 中的众多概念,如 DispatcherServlet、视图解析器 InternalResourceViewResolver。其次配置过多,新人需要关注配置文件命名规范、xml 配置文件命名空间 等。


为了解决解决上述的问题,Spring Boot 遵循约定大于配置的开发原则,大大简化的 Spring 的配置。首先进行自动化配置,只要引入相关依赖就会自动进行一些默认的配置,其次如果默认的配置不满足要求还可以自定义配置覆盖默认的配置,大大降低了 Spring 应用上手的门槛。


将上述示例改造成基于 Spring Boot 的 Spring MVC 项目,首先看下 pom 文件内容。


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.7.RELEASE</version>
    </parent>
    <groupId>com.zzuhkp</groupId>
    <artifactId>mvc-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>
    </dependencies>
</project>


和上述基于 Spring Framwork 的 pom 文件相比,主要有4处不同。


引入了一个名为 spring-boot-starter-parent 的 parent,这是 Spring Boot 为简化 pom 文件配置提供的一个模块,内部管理了很多依赖,我们的 pom 继承这个 parent 之后很多依赖就可以省略版本号,如下面的 spring-boot-starter-web。

打包方式由 war 改成 jar,Spring Boot 可内嵌 Servlet 容器,可直接使用 jar 包启动,因此无需打包为 war 再部署。

引入了 spring-boot-starter-web 依赖,这个依赖被称为 starter,spring-boot-starter 会引入一些本模块相关的依赖和自动化配置,spring-boot-starter-web 就内嵌了 Tomcat,并自动进行 Spring MVC 的配置,如 DispatcherServlet。

引入了 tomcat-embed-jasper 依赖,这个依赖的作用在于支持内嵌 Tomcat 解析 jsp。

Spring Boot 项目由于使用 jar 包启动,因此需要提供一个主类,我们定义的主类如下。


@SpringBootApplication


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


@SpringBootApplication 注解主要用于开启自动化配置,main 方法则用于启动 Spring 容器。至此一个 Spring Boot 项目其实已经搭建完成了,不再需要进行繁杂的 web.xml 配置及 Spring 配置。


虽然引入 spring-boot-starter-web 之后自动进行了 Web 开发相关的配置,不过由于我们需要自定义 InternalResourceViewResolver 的使用的视图前缀和后缀,我们还需要进一步的配置。Spring Boot 支持将相关配置直接添加到 /application.properties,看下我们的配置内容。


spring.mvc.view.prefix=/WEB-INF/page
spring.mvc.view.suffix=.jsp


是不是很简单,JSP 文件和 Controller 未做变动,仍使用前面示例的代码。看下现在的项目结构。

.
├── pom.xml
└── src
    └── main
        ├── java
        │   └── com
        │       └── zzuhkp
        │           └── mvc
        │               ├── HelloController.java
        │               └── MvcApplication.java
        ├── resources
        │   └── application.properties
        └── webapp
            └── WEB-INF
                └── page
                    └── hello.jsp


启动 main 方法,得到了和前面示例一样的效果。


总结 Spring Boot 简化应用创建的方式为:使用 spring-boot-starter-parent 管理依赖版本、使用 spring-boot-starter 自动化配置、支持用户自定义配置覆盖默认配置。


Spring Boot 是如何简化应用开发的?

Spring Boot 自动化配置不仅作用于用于应用创建,减少配置就是减少开发工作量,因此对开发效率的提升也有一定帮助。除此之外,Spring Boot 还提供了一个模块 spring-boot-devtools 用于支持 Spring Boot 项目开发时的热部署,可以通过如下的方式进行引入。


<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-devtools</artifactId>
  <scope>runtime</scope>
  <optional>true</optional>
</dependency>


引入这个依赖后,当我们的类发生变化,Spring Boot 会自动进行重启,当然了这个重启不是完整的重启,因此速度上会快上不少。


Spring Boot 是如何简化应用运行的?

对于应用运行的简化,主要提现在内嵌 Servlet 容器,能够将我们的应用自动打成 jar 包启动。上面的示例是我们在 IDE 中运行的,为了打成 jar 包,我们需要引入一个 Spring Boot 专有的插件。


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


这个插件可以将 Spring Boot 项目依赖的所有 jar 包打包到一个 jar 包中,这个 jar 也被称为 fat jar,后面我们会深入研究。


总结

Spring 官网将 Spring Boot 的核心特性总结为 6 点,在我们上述的例子中也基本有体现:


创建独立的 Spring 应用程序。

内嵌 Tomcat、Jetty 或 Undertow (无需部署 war 文件)。

提供 starter 简化配置。

尽量进行 Spring 和第三方库的自动化配置。

提供生产就绪功能,例如指标、健康检查和外部化配置。

完全无需代码生成,无需 XML 配置。

所有的 Spring Boot 内容都围绕这几大特性,本篇只是对 Spring Boot 做一个初步的认识,后面将对各特性进行深入的介绍和探索。在看的小伙伴,不如点个赞再走?


目录
相关文章
|
4月前
|
Java 应用服务中间件 Maven
SpringBoot 项目瘦身指南
SpringBoot 项目瘦身指南
122 0
|
4月前
SpringBoot+Mybatis-Plus+PageHelper分页+多条件查询
SpringBoot+Mybatis-Plus+PageHelper分页+多条件查询
109 0
|
11月前
|
JSON Java 数据格式
三万字盘点Spring/Boot的那些常用扩展点(下)
Spring对于每个Java后端程序员来说肯定不陌生,日常开发和面试必备的。本文就来盘点Spring/SpringBoot常见的扩展点,同时也来看看常见的开源框架是如何基于这些扩展点跟Spring/SpringBoot整合的。 话不多说,直接进入正题。
|
4月前
|
XML Java 数据库连接
Spring Boot的数据访问之Spring Data JPA以及Hibernate的实战(超详细 附源码)
Spring Boot的数据访问之Spring Data JPA以及Hibernate的实战(超详细 附源码)
79 0
|
3月前
|
运维 Java 关系型数据库
Spring运维之boot项目bean属性的绑定读取与校验
Spring运维之boot项目bean属性的绑定读取与校验
42 2
|
3月前
|
存储 运维 Java
Spring运维之boot项目开发关键之日志操作以及用文件记录日志
Spring运维之boot项目开发关键之日志操作以及用文件记录日志
51 2
|
3月前
|
Java Maven
springboot项目打jar包后,如何部署到服务器
springboot项目打jar包后,如何部署到服务器
247 1
|
3月前
|
XML 运维 Java
Spring运维之boot项目打包jar和插件运行并且设置启动时临时属性和自定义配置文件
Spring运维之boot项目打包jar和插件运行并且设置启动时临时属性和自定义配置文件
40 1
|
3月前
springboot2.4.5使用pagehelper分页插件
springboot2.4.5使用pagehelper分页插件
|
3月前
|
缓存 运维 Java
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
34 0