2W 字长文带你从核心拆解 Spring Boot

1,148 阅读12分钟

微信公众号:代码宇宙。只为不一样的编码体验。

SpringBoot 看似非庞然大物,却又是整个 Spring Framework 的精华,本文尽可能的基于对 SpringBoot 官方文档进行入门式讲解,示例尽可能的简单易懂,目的就是帮助你快速上手,希望对你学习 SpringBoot 有所帮助。

鉴于 SpringBoot 版本变化或环境不同容易导致难以解决的问题,笔者假定读者 Spring Boot 版本为 2.2.5,并且编辑器为 Intellij IDEA 2019.3.1

1. SpringBoot 是什么?

引用 Spring Boot 官方介绍说明

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".Most Spring Boot applications need very little Spring configuration.

SpringBoot 使创建基于 Spring 基于生产级的应用变得简单,你只需要去运行它。大多数 SpringBoot 应用程序仅仅需要很少的 Spring 配置。

2. 核心概念

相信接触过 Spring 的同学都领略过 Spring 的强大,但是繁琐又容易出错的的 XML 配置又时长让人抓狂,SpringBoot 的问世,就是来解决的这个问题的。

SpringBoot 让多数依赖开箱即用,或仅需少量 yml配置,这样的好处完全取决于 SpringBoot使用了约定大于配置的设计。

  • 开箱即用,随着需求变化你可以修改自动配置的默认值,来适应业务发展。

  • 提供一系列大型项目通用的非功能性功能(例如嵌入式服务器,安全性,指标,运行状况检查和外部化配置)。

  • 完全没有代码生成,也不需要XML配置。

3. 环境搭建

在搭建环境之前你需要准备好 Maven 3.3+ 版本并且安装了 JDK1.8

SpringBoot 官方提供了 MvaenSpring Boot CLIGradleSDKMANMacPorts 等等安装SpringBoot的方式,我们从简出发,不使用这些安装方式,直接使用 https://spring.io/ + IDEA 来开始第一个应用程序

依次打开 IDEA,File > New > Project 选择 Spring Initializr 然后 Next 可以看到填写项目信息界面如下

继续 Next,会让我们选择项目依赖,没错,以后这些事情都可以交给 IDEA 来做,但是处于学习目的我们直接一路 Next,输入项目名:SpringBootDemo(当然你可以自由发挥项目名字,但是我推荐你和我使用一样的项目名),至于依赖嘛,待会~ 我们手动添加。

首先,不熟悉 Maven的同学注意了,在项目第一次打开的时候,IDEA会提示你是否导入依赖,建议你选择自动导入。

至此,项目搭建完成,项目结构如下:

DemoApplication 就是 SpringBoot的启动类,直接 右键 > Run 运行一下试试

这就完了?为什么一运行就结束了呢?难道不应该蹦出浏览器显示 HelloWolrd 么?

因为在开始的时候并没有选择 SpringMvVC 作为依赖项,目前项目仅仅是 SpringBoot 的骨架程序。

,只是一个空壳子啊。莫慌,下面,引入 mvc。

4. 引入 Spring MVC

首先,我们打开 MavenSpringBoot的官方仓库:mvnrepository.com/artifact/or…

该仓库包含了近乎所有官方支持的 Starter 依赖,你可以理解 Starter 依赖是遵循 SpringBoot 依赖大于配置的约定构建的软件包,它可以让我们开箱即用

进入 Spring Boot Web Starter 2.2.5页面,下面输入框内就是我们要找的东西

XML 复制到项目中 pom.xml 中,复制完后记得按一下 ctrl + s 激活一下自动导入

配置完了 SpringBoot MVC 直接启动一下,会发现程序监听了 8080 端口,虽然我们没有编写任何的配置文件,但是 SpringBoot 已经帮我们做了好几件事:

  • 端口默认配置
  • 默认的视图解析器
  • 默认的包扫描配置
  • 等等等等

尝试修改端口,在 application.properties 中添加配置 server.port=1024 再次启动,发现 程序监听端口由 8080 变为了 1024

刚才的操作,称之为 覆盖 SpringBoot 默认配置,可以覆盖的默认配置有很多,更多的配置可查阅 spring-boot-autoconfigure-2.2.5.RELEASE.jar 下的 web 包,这里不做太多介绍,至此 年轻人第一个 SpringBoot 程序构建完成。

5. 第一个静态资源访问

在没有配置任何的视图解析器的情况下,Spring MVC 默认只可以进行静态资源访问,比如 html、css、js、图片等等,下面我们就试一下访问静态资源吧,直接开搞!

在resources目录下新建文件夹 static ,然后新建 index.html 文件如下:

在这里插入图片描述
第一个静态资源就完成了,那么,为什么是 static,不是 lalala,不是 hahaha

这就要说到 SpringBoot 的默认配置了,SpringBoot 默认约定 resources 目录下 staticpublic、以及根目录为静态资源的位置,源码配置如下,大家可以参阅

在这里插入图片描述
全部新建完毕后,我们启动服务,访问 http://localhost:1024/index.html 试试
在这里插入图片描述
Nice,所有的静态资源你都可以放在 static 下面,而不用去配置任何东西,如果你想放在其他目录下,则需要在 application.properties 中配置如下内容:

spring.resources.static-locations= 'classpath:/web-app/static/'

6. 第一个接口

配置完 SpringMVC ,接下来要干嘛?当然是写接口了!

com.example.demo 下新建包 controller (控制器的意思,相当于 Servlet),在 controller下新建类 HelloController 如下:

在这里插入图片描述
@Controller注解标识该类是一个 web 接口类,你可以理解为是一个 Servlet@RequestMapping("/api") 标识该接口的访问地址,比如这个接口的访问地址就是 :http:xxx:8080/api

下面我们新建一个方法,照着写即可,接下来会详细讲 为什么

在这里插入图片描述
有同学可能会疑问,@RequestMapping 类上不是已经有了吗为什么方法上还有,@RequestMapping 的作用域为类或者方法,在 Controller 类上修饰的话标识该类的接口全部以 /api 为前缀访问,比如我们写的这个方法的访问地址就为 /api/test1

那么,@RequestBody又是什么呢?@RequestBody 是SpringMVC为我们提供的转换注解,表示我们这个网址不是返回的一个页面,而是返回的一个对象,SpringMVC 对标识了该注解的接口会自动将数据转换为 json 返回到页面中,方便我们前端或者是移动端使用哦!

接下来,我们启动服务访问一下吧!

在这里插入图片描述
我们看到 浏览器已经响应了结果。

7. 第一次连接数据库

上面的例子让我们实现了接口返回数据,举一反三你可以写出很多复杂的接口,但是,没有数据库的支持,都是死数据,没意思,对吧,废话不多说,不搞 JDBC 不搞 hibernate ,直接上现代化 mybatis 框架

Spring 在之前集成 mybatis 相当复杂,需要配置很多的xml。在 SpringBoot 上集成 Mybatis 就变得简单的多,直接在 pom.xml 中 添加依赖:

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>1.3.1</version>
</dependency>

以mysql为例,当然,你想连接什么数据库仅需引入什么数据库的驱动依赖即可 第一个依赖是 mysql 的驱动依赖 第二个是 mybatis 提供的 SpringBoot starter 帮助我们快速配置并启用 mybatis

首先需要创建一个数据库名称为 dmyz (也就是我的个人公众号 代码宇宙的缩写,欢迎大家关注~)我给大家准备了建表 SQL,执行即可生成 business 表和一条数据,方便大家快速测试,SQL 如下:

-- auto-generated definition
create table business_user
(
    id          int auto_increment comment '用户id'
        primary key,
    username    varchar(255) default ''                not null comment '用户名',
    password    varchar(255) default ''                not null comment '密码',
    mobile      varchar(11)  default '0'               null comment '手机号',
    email       varchar(255) default ''                null comment '邮箱',
    create_time datetime     default CURRENT_TIMESTAMP not null comment '创建时间',
    update_time datetime     default CURRENT_TIMESTAMP not null comment '更新时间',
    status      int          default 0                 not null comment '状态
0.正常
1.删除',
    constraint business_user_username_uindex
        unique (username)
)
    comment '用户基础信息表';
create table business_user
(
    id          int auto_increment comment '用户id'
        primary key,
    username    varchar(255) default ''                not null comment '用户名',
    password    varchar(255) default ''                not null comment '密码',
    mobile      varchar(11)  default '0'               null comment '手机号',
    email       varchar(255) default ''                null comment '邮箱',
    create_time datetime     default CURRENT_TIMESTAMP not null comment '创建时间',
    update_time datetime     default CURRENT_TIMESTAMP not null comment '更新时间',
    status      int          default 0                 not null comment '状态
0.正常
1.删除',
    constraint business_user_username_uindex
        unique (username)
)
    comment '用户基础信息表';

INSERT INTO ccloud.business_user (id, username, password, mobile, email, create_time, update_time, status) VALUES (1, '代码宇宙', 'e6852b1bed61b9cbfbb6683ece03c8ee', '0', '', '2020-02-22 18:19:36', '2020-02-22 18:19:36', 0);

接下来配置数据库连接,在 application.properties 中添加你的数据库信息,如果你还不了解 mysql 或者 mybatis,建议学习下。

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/dmyz
spring.datasource.username=root
spring.datasource.password=123456

然后按照下图创建一个 Mapper注意图上的 Mapper 注解)

在这里插入图片描述
这里我们使用了注解 @Select 来简化这个查询,当然,也可以使用xml的方式来实现,这里不做详细介绍。

写好了第一个Mapper 然后怎么用它呢?和传统 Spring 一样,我们可以直接在 Controller 中注入这个 Mapper 来使用,如下图:

在这里插入图片描述
这里,说下,Spring 的注入方式有三种,一种是 @Resource 注解,一种是 @Autowired 注解,还有一种是构造函数注入,官方推荐推荐使用构造函数或者是@Resource 注解注入。

好了,下面启动一下项目访问 /api/test2 试试看吧! 你会看到如下图所示的界面(你看到的可能没有高亮,因为我安装了浏览器插件的原因)

在这里插入图片描述

7. 第一个拦截器

说完了接口,来说一下拦截器吧,拦截器在实际开发过程中非常常见,主要用于 权限验证,接口过滤,参数验证等等用途,下面就来实现一个简单的拦截器。

比如说我们所有的接口,只允许携带 admin 密码的人访问,首先新建包 config,一般情况下 设计到配置的类我们都放在 config 包下以方便管理,拦截器代码如下图所示。

在这里插入图片描述
我们一步一步的解析,Spring 实现拦截器的办法有两种,一种是 HandlerInterceptor 一种是 FilterServlet 规范中的),我们选择前者。

实现preHandle方法能对请求进行过滤,或者记录日志,我在这里拿到了 admin参数并且验证参数内容是否为 代码宇宙,如果是的话放行请求,如果不是的话就不予许访问,返回 false,请求将会被中断。

最后我们需要将我们的拦截器告诉 Spring,就需要集成 WebMvcConfigurationSupport 重写 addInterceptors 并告诉拦截器我要添加一个拦截器,他要拦截的具体路径是什么。

至此,一个拦截器就实现完毕了!别忘了加 @Configuration 注解哦,这个注解是告诉Spring 这是一个 配置类,需要被加载的意思。

启动程序,打开浏览器,访问刚刚的接口 /api/test2 接口试验一下吧

在这里插入图片描述
我们看到,内容已经消失了,因为在拦截器中,获取不到 admin 参数,返回了 false,导致请求终止,我们加上 admin 参数再试一下吧。

在这里插入图片描述

看!又恢复了正常。拦截器有很多的用途,细心揣摩将会发现拦截器不止一个 方法可以重写,也不止可以获取到 get 方式提价的参数,实现权限验证其实很简单,我们可以在拦截器中获取到用户的 cookie 或者 session 然后拿到用户 id,去数据库查询到他的权限即可实现权限验证或者登陆验证。

这里需要注意 : Springboot 默认是在org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration 这个类配置默认的static 等路径,但是这个类上面配置了@ConditionalOnMissingBean(WebMvcConfigurationSupport.class) 什么意思呢?简而言之就是说,如果发现了 WebMvcConfigurationSupport 类的存在,那么这个配置将失效,我们在配置拦截器的时候,是配置了WebMvcConfigurationSupport类的。

在这里插入图片描述

那么, 怎么解决这个问题呢?很简单,只需要在 拦截器中在重写一个方法告诉 SpringBoot 那些目录是静态资源就OK 了

在这里插入图片描述

顺便,还能将你的自定义目录加进去,岂不美哉? 加完访问试一下,记得加上 admin 参数,不然是访问不通的哦~

在这里插入图片描述

4. 第一次部署到服务器

SpringBoot 由于其自带容器,无需依赖外部容器,所以我们不需要将 项目打包成 war,直接打包成 jar 丢到服务器上运行即可,步骤如下:

首先使用 maven 对项目执行 package 操作,也就是打包

在这里插入图片描述
打包完毕后控制台会输出包的位置,这就是生成的 jar 包的位置

在这里插入图片描述

直接复制到服务器,运行命令java -jar demo-0.0.1-SNAPSHOT.jar即可启动服务 但是这样启动仅仅是前台运行,要是想后台一直运行怎么办呢?nohup!

命令如下:

nohup java -jar demo-0.0.1-SNAPSHOT.jar &

5. 遇到问题怎么办?

俗话说,授人以鱼不如授人以渔,与其我将你可能遇到的问题一一告诉你,不如告诉你如何去解决一遇到的问题,这样一来,不管你遇到任何的问题,都能靠自己的能力去解决了!

打个比方,比如说刚刚我们配置完拦截器,去访问之前的静态页面发现访问不到了,首先这个问题,我们应该怎么查怎么想?

搜索:静态资源访问不到怎么办 X

这是错误的做法,这样会查到很多的原因,导致很难解决实际的问题,正确的做法是

搜索:SpringBoot 拦截器 静态资源访问不到

首先包含了框架名称,其次包含了前置事件,最后问题是什么,这样会让我们快速定位问题所在,看下结果:

在这里插入图片描述
好了,到这里,我想,你应该已经入门了,文章写得很详细,但难免有纰漏之处,遇到问题欢迎留言或者公众号反馈给我,下集主要讲进阶,会首发于公众号,谢谢!