1.1 Spring Boot 概述

1.1.1 什么是Spring Boot

Spring Boot是Spring项目中的一个子工程,与我们所熟知的Spring-framework 同属于spring的产品:

进官网: spring.io

其最主要作用就是帮助开发人员快速的构建庞大的spring项目,并且尽可能的减少一切xml配置,做到开箱即用,迅速上手,让开发人员关注业务而非配置。

主要特点:

  1. 自动配置 : 不需要再关注各个框架的整合配置, springboot全部已经配置好了

  2. 起步依赖 : 我们在需要使用某个框架的时候, 直接添加这个框架的启动器依赖即可 , 不需要再关注jar包的冲突和整合

设计目的: 用来简化 Spring 应用的初始搭建以及开发过程。

从最根本上来讲,Spring Boot 就是一些库的集合,它能够被任意项目所使用。它使用 “习惯优于配置”的理念让你的项目快速运行起来。spring boot 其实不是什么新的框架,它默认配置了很多框架的使用方式,就像 maven 整合了所有的 jar 包,spring boot 整合了所有的框架,总结一下及几点:

(1)为所有 Spring 开发提供一个更快更广泛的入门体验。

(2)零配置。无冗余代码生成和XML 强制配置,遵循“约定大于配置” 。

(3)集成了大量常用的第三方库的配置, Spring Boot 应用为这些第三方库提供了几乎可以零配置的开箱即用的能力。

(4)提供一系列大型项目常用的非功能性特征,如嵌入服务器等。

使用 Spring Boot有什么好处:

其实就是简单快速方便

平时如果我们需要搭建一个 Spring Web 项目的时候需要怎么做呢?

· 1)配置 web.xml,加载 Spring 和 Spring mvc

· 2)配置数据库连接、配置 Spring 事务

· 3)配置加载配置文件的读取,开启注解

· 4)配置日志文件

· …

· 配置完成之后部署 Tomcat 调试

· …

1.1.2 Spring Boot的优势

使用Java开发程序 , 一直困扰我们的就是臃肿、麻烦。搭建项目的过程相当复杂 , 我们需要考虑很多问题 , 主要的问题有如下两点 :

\1. 复杂的配置

\2. 混乱的依赖管理

Spring Boot帮我们解决了这个些, 我们在使用Spring Boot开发时, 不需要关注各种复杂的整合配置 , 也不用关注各个库之间的依赖及冲突问题 , Spring Boot已经默认帮我们整合配置好了 !

节省了大量的配置及依赖调整时间, 让我们能够把时间用在刀刃上, 专注业务逻辑的开发。

1.2 Spring Boot 快速入门

学习网站:

https://spring.io/quickstart

https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html#getting-started.installing

1.2.1 需求

需求:访问 http://localhost:8080/hello输出 “Hello Spring Boot”

1.2.2 步骤

  1. 创建Maven工程

  2. 添加依赖(springboot父工程依赖 , web启动器依赖)

  3. 编写启动引导类(springboot项目运行的入口)

  4. 编写处理器Controller

  5. 启动项目

1.2.3 实现

创建项目: springboot_01

1.2.3.1 创建工程

1.2.3.2 添加依赖

SpringBoot可以帮我们方便的管理项目依赖 , 在Spring Boot提供了一个名为spring-boot-starter-parent的工程,里面已经对各种常用依赖的版本进行了管理,我们的项目需要以这个项目为父工程,这样我们就不用操心依赖的版本问题了,需要什么依赖,直接引入坐标(不需要添加版本)即可!

1) 添加父工程坐标

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
</parent>

2) 添加web启动器

为了让Spring Boot帮我们完成各种自动配置,我们必须引入Spring Boot提供的自动配置依赖,我们称为启动器。因为我们是web项目,这里我们引入web启动器,在 pom.xml 文件中加入如下依赖:

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

需要注意的是,我们并没有在这里指定版本信息 , 当我们添加好启动器之后我们发现项目中已经依赖了大量的Jar包

3) 配置JDK版本

<properties>
<java.version>1.8</java.version>
</properties>

思考: 为什么我们这里仅仅配置了这么一个变量 , 项目的JDK版本就会改变呢 ?

因为jdk插件已经在父工程中定义好了 , 默认会读取${java.version}变量值

4) 完整的pom.xml文件

配置完毕之后完整的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>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
</parent>

<groupId>com.atguigu</groupId>
<artifactId>springboot_01</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>


<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>


</project>

1.2.3.3 创建启动类

Tips:启动类必须要放在一个包内

Spring Boot项目通过main函数即可启动,我们需要创建一个启动类:

(这里我用了两种方式实现,所以代码会import一些用过的包,会显示灰色)

package com.atguigu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
* @author wh
* @CREATE 2023/5/24 10:53
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}

1.2.3.4 编写controller

package com.atguigu.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* @author wh
* @CREATE 2023/5/24 11:04
*/

/*
* 在Spring中@RestController的作用等同于@Controller + @ResponseBody
* 学习链接:https://www.cnblogs.com/yaqee/p/11256047.html
* https://blog.csdn.net/u010412719/article/details/69710480
* */
@RestController
public class HelloController {

/*1) SpringMVC使用@RequestMapping注解为控制器指定可以处理哪些 URL 请求。
2) DispatcherServlet 截获请求后,就通过控制器上 @RequestMapping 提供的映射信息确定请求所对应的处理方法。
标记在方法上:提供进一步的细分映射信息。相对于标记在类上的 URL。
*/
@RequestMapping("/hello")
public String sayHello() {
return "hello spring boot!!";
}
}



1.2.3.5 启动测试

运行启动类的main方法 :

控制台会输出如下信息 :

通过输出的日志我们知道了以下信息 :

  1. 监听的端口是8080

  2. 项目的上下文路径是””

打开浏览器,访问:http://localhost:8080/hello

1.3 Spring Boot 入门 – 思考

问题1:

为什么我们在添加启动器的时候不需要在启动器的坐标中指定版本?

答案:因为我们指定了项目的父工程,在spring-boot-starter-parent中已经通过Maven的版本锁定了Jar包的版本,所以就不需要再指定了。

问题2:

为什么我们就添加一个启动器依赖,项目就可以运行起来了,运行项目所需要的Jar包从何而来?

答案:因为我们添加了这个启动器的依赖,它已经把自己运行所需要的必要包集成在这个启动器中,通过Maven的依赖传递性,将这些包都依赖到咱们的项目里了。

点击项目右键 open module settings

1.4 配置文件详解

springboot支持二种类型的配置文件

  • properties属性配置文件

  • yaml配置文件(同yml—推荐)

    ​ (因为可以用缩进来表示层级)

配置文件必须放置在项目的类加载目录下(resources), 并且名字必须是application*(不严谨,看下面源码)

springboot项目在运行的时候会自动加载这些配置文件

同级目录下打开:spring-configuration-metadata.json

搜素:server.port

为什么可以在resources下创建application.properties文件呢?我们查看springboot的启动依赖:

点击spring-boot-starter-parent

1.4.1 属性配置文件

resource 文件夹下面新建 application.properties 配置文件

spring.jdbc.datasource.driverClassName=com.mysql.jdbc.driver
spring.jdbc.datasource.url=jdbc:mysql:///springboot_01
spring.jdbc.datasource.username=root
spring.jdbc.datasource.password=root

新建 properties 包,创建类 DataSourceProperties

package com.atguigu.properties;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
* @author wh
* @CREATE 2023/5/24 16:09
*/

/*
* @Component:
* 标注Spring管理的Bean,使用@Component注解在一个类上,表示将此类标记为Spring容器中的一个Bean。
* 学习链接:https://blog.csdn.net/Thinkingcao/article/details/71171222
* */
@Component
public class DataSourceProperties {

/*
@Value:
在使用spring框架的项目中,@Value是经常使用的注解之一。
其功能是将与配置文件中的键对应的值分配给其带注解的属性。
学习链接:https://blog.csdn.net/qq_31960623/article/details/116902786
* */

@Value("${spring.jdbc.datasource.driverClassName}")
private String driverClassName;
@Value("${spring.jdbc.datasource.url}")
private String url;
@Value("${spring.jdbc.datasource.username}")
private String username;
@Value("${spring.jdbc.datasource.password}")
private String password;

// 生成get set 和 toString方法

public String getDriverClassName() {
return driverClassName;
}

public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

@Override
public String toString() {
return "DataSourceProperties{" +
"driverClassName='" + driverClassName + '\'' +
", url='" + url + '\'' +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}

controller 添加 sayHello 方法

package com.atguigu.controller;

import com.atguigu.properties.DataSourceProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* @author wh
* @CREATE 2023/5/24 11:04
*/

/*
* 在Spring中@RestController的作用等同于@Controller + @ResponseBody
* 学习链接:https://www.cnblogs.com/yaqee/p/11256047.html
* https://blog.csdn.net/u010412719/article/details/69710480
* */
@RestController
public class HelloController {


/*自动装配
* 默认是根据属性类型,spring自动将匹配到的属性值进行注入,然后就可以使用这个属性
* (对HelloController类来说)DataSourceProperties对象的方法
* https://blog.csdn.net/weixin_45755816/article/details/118654961*/
@Autowired
private DataSourceProperties dataSourceProperties ;



/*1) SpringMVC使用@RequestMapping注解为控制器指定可以处理哪些 URL 请求。
2) DispatcherServlet 截获请求后,就通过控制器上 @RequestMapping 提供的映射信息确定请求所对应的处理方法。
标记在方法上:提供进一步的细分映射信息。相对于标记在类上的 URL。
*/
@RequestMapping("/hello")
public String sayHello() {
System.out.println(dataSourceProperties);
return "hello spring boot!!";
}
}



请求地址:http://localhost:8080/hello

控制台打印:

1.4.2 YAML配置文件

何谓YAML?

YAML是一种配置文件格式

基本格式:

语法 :

1.数据结构用树形结构呈现,通过缩进来表示层级,

2.连续的项目通过减号 ” - ” 来表示

3.键值结构里面的key/value对用冒号 ” : ” 来分隔。

4.YAML配置文件的扩展名是yaml 或 yml

resource 文件夹下面新建 application.yml 配置文件,修改 application.properties 配置文件名字为 application.properties.bak(忽略掉,因为有优先级)

spring:
jdbc:
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql:///springboot_01
username: root
password: root

运行项目,重新请求 http://localhost:8080/hello

yml配置文件的特征:

  1. 树状层级结构展示配置项;

  2. 配置项之间如果有关系的话需要分行,空两格;

  3. 配置项如果有值的话,那么需要在 :之后空一格再写配置项值;

yaml****与properties配置文件除了展示形式不相同以外,其它功能和作用都是一样的

1.4.3 多环境profile切换配置

我们刚刚说过在Spring Boot项目中配置文件的名称只能是application , 如果我们把所有的配置全都写在一个配置文件中如果配置项比较多, 配置文件就会显得比较复杂和臃肿 ! 不利于后期的项目维护和开发

例如下面几个场景 :

1.因为开发环境的变化, 我们需要修改配置文件中某一个配置项的值(比如之前是mysql数据库,切换成oracle数据库)

2.项目开发完成需要上线了 , 需要把一些环境修改成正式环境(开发测试上线,多环境切换)

解决方案 :使用profiles拆分配置

spring boot项目中允许使用多个YAML配置文件。

这些文件名称必须为application-***.yml,并且在application.yml中激活。

创建application-dev.yml文件如下:

# 配置数据库连接池信息 ,开发环境
spring:
jdbc:
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql:///springboot
username: root
password: root

创建application-pro.yml文件如下:

# 配置数据库连接池信息,上线环境
spring:
jdbc:
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql:///business
username: business
password: business

application.yml 文件中添加如下配置:

# 激活配置文件
spring:
profiles:
active: dev

直接运行项目:http://localhost:8080/hello

打印结果:

DataSourceProperties{driverClassName='com.mysql.jdbc.Driver', url='jdbc:mysql:///springboot', username='root', password='root'}

修改 application.yml 配置文件:

# 激活配置文件
spring:
profiles:
active: pro

打印结果:

DataSourceProperties{driverClassName='com.mysql.jdbc.Driver', url='jdbc:mysql:///business', username='business', password='business'}

注意 :

如果properties和yml文件都存在,不存在spring.profiles.active设置,如果有重叠属性,默认以properties优先。
如果设置了spring.profiles.active,并且有重叠属性,以active设置优先。
可以在两种文件中分别增加server.port属性指定不同的端口,启动项目查看控制台端口号进行测试。

二. Spring Boot 自动配置(理解)

学习链接:https://docs.spring.io/spring-boot/docs/current/reference/html/

2.1 @SpringBootApplication注解

· @SpringBootConfiguration : 代表这个类就是一个配置类 , 本质上就是一个@Configuration注解

​ @Configuration:添加了该注解的类将是一个配置类,用来代替xml配置文件

· @ComponentScan : 组件扫描, 默认扫描启动类所在包及子包下的类身上的注解

· @EnableAutoConfiguration : 自动配置注解 , 添加了此注解会自动去读取spring.factories配置文件中的自动配置类

2.2 @ConfigurationProperties注解

@ConfigurationProperties是SpringBoot提供的重要注解, 他可以将一些配置属性批量注入到bean对象。

application.yml配置文件

spring:
jdbc:
datasource:
driverClassName: com.mysql.jdbc.driver
url: jdbc:mysql:///springboot_01
username: root
password: root

DataSourceProperties.java

public class DataSourceProperties {

private String driverClassName;
private String url;
private String username;
private String password;

// 省略getter和setter.....
}

方式一 : 使用@Value一个个注入

这种注入方式,如果属性特别多,一个一个注入太麻烦

@Component
public class DataSourceProperties {

@Value("${spring.jdbc.datasource.driverClassName}")
private String driverClassName;
@Value("${spring.jdbc.datasource.url}")
private String url;
@Value("${spring.jdbc.datasource.username}")
private String username;
@Value("${spring.jdbc.datasource.password}")
private String password;

// 省略getter和setter.....
}

方式二 : 使用@ConfigurationProperties批量注入

这种注入方式,属性再多,只要按照规则就可以一次性自动注入。方便的很

package com.atguigu.properties;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
* @author wh
* @CREATE 2023/5/24 16:09
*/

/*
* @Component:
* 标注Spring管理的Bean,使用@Component注解在一个类上,表示将此类标记为Spring容器中的一个Bean。
* 学习链接:https://blog.csdn.net/Thinkingcao/article/details/71171222
* */
/*
* • 在类上通过@ConfigurationProperties注解声明该类要读取属性配置
• prefix="spring.jdbc.datasource" 读取属性文件中前缀为spring.jdbc.datasource的值。前缀和属性名称和配置文件中的key必须要保持一致才可以注入成功
• Spring Boot默认读取application.properties属性文件
如何使用:
* 在controller开启@ConfigurationProperties注解使用:@EnableConfigurationProperties(DataSourceProperties.class)
* 报红在pom.xml中添加依赖:
* <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

* */
@Component
@ConfigurationProperties(prefix = "spring.jdbc.datasource")
public class DataSourceProperties {

/*
@Value:
在使用spring框架的项目中,@Value是经常使用的注解之一。其功能是将与配置文件中的键对应的值分配给其带注解的属性。
学习链接:https://blog.csdn.net/qq_31960623/article/details/116902786
* */

// @Value("${spring.jdbc.datasource.driverClassName}")
private String driverClassName;
// @Value("${spring.jdbc.datasource.url}")
private String url;
// @Value("${spring.jdbc.datasource.username}")
private String username;
// @Value("${spring.jdbc.datasource.password}")
private String password;
// 省略getter和setter.....
}

开启@ConfigurationProperties注解使用

@Controller
@EnableConfigurationProperties(DataSourceProperties2.class)
public class HelloController {

@Autowired
private DataSourceProperties2 dataSourceProperties2 ;

@RequestMapping(path = "/hello")
@ResponseBody
public String sayHello(){
System.out.println(dataSourceProperties2);
return "hello spring boot";
}
}

使用@EnableConfigurationProperties(DataSourceProperties2.class),开启DataSourceProperties2身上的@ConfigurationProperties注解 , 他就会生效了, 就会帮助我们注入数据了

请求地址:http://localhost:8080/hello

打印结果:

DataSourceProperties2{driverClassName='com.mysql.jdbc.Driver', url='jdbc:mysql:///springboot_01', username='root', password='root'}

报错提示,请在pom文件添加配置信息

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

方式三:对象属性注入

**注意 : @ConfigurationProperties不仅可以自动注入简单类型数据, 也支持对象属性引导 **

待定。。。

2.3 条件化配置注解

我们看到自动配置类上有一些ConditionXxxx注解 , 这些注解的作用就是进行条件化选择

所谓条件化选择就是如果满足条件, 该配置类就生效, 如果不满足该配置类就不生效

常用的条件化选择注解如下 :

注解 作用
@ConditionalOnBean 如果存在某个Bean, 配置类生效
@ConditionalOnMissingBean 如果不存在某个Bean, 配置类生效
@ConditionalOnClass 如果存在某个类, 配置类生效
@ConditionalOnMissingClass 如果不存在某个类, 配置类生效
@ConditionalOnProperty 如果存在某个属性配置, 配置类生效
@ConditionalOnWebApplication 如果是一个web应用, 配置类生效
@ConditionalOnNotWebApplication 如果不是一个web应用, 配置类生效

因为我们配置了DispatcherServlet 满足上面定义的条件, 所以WebMvcAutoConfiguration会生效 , 那么WebMvcAutoConfiguration自动配置类中帮我们配置了什么呢 ?

视图解析器

处理器适配器(HandlerAdapter)

这些配置都是我们之前在学习SpringMVC时需要自己配置的 , 现在Spring Boot框架都已经提前帮我们配置好了 , 所以我们才能使用的那么方便

三. Spring Boot常用启动器(掌握)

学习链接:https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using

3.1 SpringMVC复习

3.1.1SpringMVC处理请求的简单流程图

基本步骤:

  1. 客户端请求提交到DispatcherServlet

  2. 由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller

  3. DispatcherServlet将请求提交到Controller(也称为Handler)

  4. Controller调用业务逻辑处理后,返回ModelAndView

  5. DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图

  6. 视图负责将结果显示到客户端

3.1.2SpringMVC中的主要组件

  1. DispatcherServlet:前端控制器

  2. Controller:页面控制器/处理器,做的是MVC中的C的事情,但控制逻辑转移到前端控制器了,用于对请求进行处理。

  3. HandlerMapping :请求映射到处理器,找谁来处理,如果映射成功返回一个HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器对象)

  4. HandlerAdaptor:处理器适配器

  5. ViewResolver : 视图解析器,找谁来处理返回的页面。把逻辑视图解析为具体的View,进行这种策略模式,很容易更换其他视图技术:

  • 如InternalResourceViewResolver将逻辑视图名映射为JSP视图
  1. MultipartResolver:文件上传解析器

  2. HandlerExceptionResolver:异常处理器

3.1.3拦截器简介

  1. Spring MVC也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义的拦截器可以实现HandlerInterceptor接口,也可以继承HandlerInterceptorAdapter 适配器类。

  2. HandlerInterceptor接口方法说明:

a) preHandle():这个方法在业务处理器处理请求之前被调用,可以在此方法中做一些权限的校验。如果程序员决定该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去进行处理,则返回true;如果程序员决定不需要再调用其他的组件去处理请求,则返回false。

b) postHandle():这个方法在业务处理器处理请求之后,渲染视图之前调用。在此方法中可以对ModelAndView中的模型和视图进行处理。

c)afterCompletion():这个方法在 DispatcherServlet 完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。

3.2SpringMVC复习之配置单个拦截器

3.2.1 创建一个类实现HandlerInterceptor接口

package com.atguigu.springmvc.interceptors;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FirstInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("FirstInterceptor的preHandle方法执行");
return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("FirstInterceptor的postHandle方法执行");
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("FirstInterceptor的afterCompletion方法执行");
}


}

3.2.42在SpringMVC配置文件中配置拦截器示例

<!--配置拦截器-->
<mvc:interceptors>
<!--声明定义的拦截器
通过这种方式定义的拦截器会拦截所有请求
-->
<bean id="firstInterceptor" class="com.atguigu.springmvc.interceptors.FirstInterceptor"></bean>
</mvc:interceptors>

3.2.3 单个拦截器的执行流程图

3.3 SpringBoot整合MVC

创建项目 springboot_02_mvc

3.3.1 起步依赖

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

① 新建入口程序类 MvcApplication

package com.atguigu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* @author wh
* @CREATE 2023/5/29 11:36
*/
@SpringBootApplication
public class MvcApplication {
public static void main(String[] args) {
SpringApplication.run(MvcApplication.class,args);
}
}

② 新建 javabean

package com.atguigu.pojo;

/**
* @author wh
* @CREATE 2023/5/29 11:37
*/
public class User {
private String username ;
private String password ;
private Integer age ;
private String sex ;
// 省略getter和setter.....
}

③ 新建 UserController

package com.atguigu.controller;

import com.atguigu.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
* @author wh
* @CREATE 2023/5/29 11:38
*/
/*
* SpringMVC中要创建控制器/处理器: 在类上添加@Controller注解标识当前类是一个处理器
* @RequestMapping标记在类上:提供初步的请求映射信息。相对于WEB 应用的根目录
* */
@RestController
@RequestMapping(path = "/user")
public class UserController {


/* @ResponseBody表示方法的返回值直接以指定的格式写入Http response body中,而不是解析为跳转路径。

   格式的转换是通过HttpMessageConverter中的方法实现的,因为它是一个接口,因此由其实现类完成转换。

如果要求方法返回的是json格式数据,而不是跳转页面,可以直接在类上标注@RestController,
而不用在每个方法中标注@ResponseBody,简化了开发过程。*/
@RequestMapping(path = "/findAll")
@ResponseBody
public List<User> findAll(){
//查询所有
List<User> users = new ArrayList<User>();

User user1 = new User();
user1.setUsername("杨过");
user1.setPassword("123456");
user1.setAge(18);
user1.setSex("男");

User user2 = new User();
user2.setUsername("杨过");
user2.setPassword("123456");
user2.setAge(18);
user2.setSex("男");

User user3 = new User();
user3.setUsername("杨过");
user3.setPassword("123456");
user3.setAge(18);
user3.setSex("男");

users.add(user1);
users.add(user2);
users.add(user3);

return users ;
}

}

运行程序 :http://localhost:8080//user/findAll

3.3.2 静态资源目录

在WEB开发中我们经常需要引入一些静态资源 , 例如 : HTML , CSS , JS , 图片等 , 如果是普通的项目静态资源可以放在项目的webapp目录下

现在使用Spring Boot做开发 , 项目中没有webapp目录 , 我们的项目是一个jar工程,那么就没有webapp,我们的静态资源该放哪里呢?

在springboot中有一个叫做ResourceProperties的类,里面就定义了静态资源的默认查找路径:

默认的静态资源路径为:

· classpath:/META-INF/resources/

· classpath:/resources/

· classpath:/static/

· classpath:/public

我们只要静态资源放在这些目录中任何一个,SpringMVC都会帮我们处理。 我们习惯会把静态资源放在classpath:/static/ 目录下。在resources目录下创建index.html文件/插入图片

打开浏览器输入 : http://localhost:8080/index.html

打开浏览器输入 : http://http://localhost:8080/Snipaste_2023-05-29_15-46-02.png

覆盖路径

如果想要修改默认的静态资源路径, 配置如下 :

新建 application.yml

spring:
resources:
static-locations: classpath:/webapp/

3.3.3 自定义拦截器

Tips:重写方法可以用alt+insert快捷键

web开发中的拦截器也是我们经常需要使用的组件,可以帮我们完成一些日志记录 , 数据过滤 , 请求过滤等等很多功能,那么在SpringBoot中该如何配置呢?

回顾一下SpringMVC中配置拦截器的步骤 :

  1. 编写一个拦截器(实现HandlerInterceptor接口)

  2. 注册拦截器(mvc:interceptors)

第一步不变,第二步的xml文件用配置类替代
xml

<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--配置拦截路径-->
<mvc:mapping path="/user/**"/>
<!--配置不拦截路径:不拦截路径是指从拦截路径中排除-->
<mvc:exclude-mapping path="/user/sayByby"></mvc:exclude-mapping>
<!--配置拦截器bean-->
<bean class="com.atguigu.interceptor.LogInterceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>

因为SpringBoot没有XML配置文件了 , 所以在SpringBoot中使用拦截器的注册拦截器的方式就不太一样了, 需要借助一个WebMvcConfigurer类帮助我们注册拦截器 , 实现拦截器的具体步骤如下 :

  1. 编写一个拦截器

  2. 通过WebMvcConfigurer注册拦截器

编写拦截器

package com.atguigu.interceptor;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* @author wh
* @CREATE 2023/5/31 10:04
*/
@Component
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
//这里return true,否则不会过postHandle 和 afterCompletion
System.out.println("MyInterceptor拦截器的preHandle方法执行....");
return true;
}

@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor拦截器的postHandle方法执行....");
}

@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyInterceptor拦截器的afterCompletion方法执行....");
}
}

注册拦截器

package com.atguigu.config;

import com.atguigu.interceptor.MyInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
* @author wh
* @CREATE 2023/5/31 10:07
*/
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Autowired
private MyInterceptor myInterceptor;
/**
* /** 拦截当前目录及子目录下的所有路径 /user/** /user/findAll /user/order/findAll
* /* 拦截当前目录下的以及子路径 /user/* /user/findAll
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor).addPathPatterns("/**");
}
}

打开浏览器,输入 : http://localhost:8080/user/findAll

3.4 SpringBoot整合Spring Data JPA

JDBC框架:

  1. Mybatis
  2. JPA
  3. 通用Mapper
  4. Mybatis-Plus

编写代码顺序

新建项目 springboot_jpa

添加Spring Data JPA的起步依赖

<?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.atguigu.springboot</groupId>
<artifactId>springboot_jpa</artifactId>
<version>1.0-SNAPSHOT</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/>
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<!-- springBoot JPA的起步依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- MySQL连接驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

<!-- 配置使用redis启动器 -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-redis</artifactId>-->
<!-- </dependency>-->

</dependencies>


</project>

创建启动类

package com.atguigu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* @author wh
* @CREATE 2023/5/29 11:36
*/
@SpringBootApplication
public class JpaApplication {
public static void main(String[] args) {
SpringApplication.run(JpaApplication.class,args);
}
}

在application.yml中配置数据库和jpa的相关属性

logging:
level:
com.atguigu.dao: debug # 配置日志
spring:
datasource:
username: root
password: root
url: jdbc:mysql://127.0.0.1:3306/springboot?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
database: mysql
show-sql: true
generate-ddl: true
hibernate:
ddl-auto: update
naming_strategy: org.hibernate.cfg.ImprovedNamingStrategy
server:
port: 18081

创建数据库 库名springboot

此处设置了generate-ddl: true,所以可以不用创建表,会自动创建user表

注意:Mysql8.x版本,连接时url需要指定时区,并且驱动类包名发生了变化。

(改完配置文件后重启mysql)

创建实体配置实体

package com.atguigu.domain;
import javax.persistence.*;

@Entity //可以将对象作为一张表按照表名持久化/映射到数据库中
@Table(name = "user")
public class User{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) //主键/自增长
@Column(name = "id")
private Long id;
@Column(name = "username")
private String username;
@Column(name = "password")
private String password;
@Column(name = "name")
private String name;

//此处省略setter和getter方法... ...
}

这里如果报红可以不用管Cannot resolve table ‘user’

编写UserDao

package com.atguigu.dao;

import com.atguigu.pojo.User;
import org.springframework.data.jpa.repository.JpaRepository;

/**
* @author wh
* @CREATE 2023/5/31 14:52
*/
public interface UserDao extends JpaRepository<User,Integer> {
}

编写service类

package com.atguigu.service;

import com.atguigu.pojo.User;

import java.util.List;

/**
* @author wh
* @CREATE 2023/5/31 14:54
*/
public interface UserService {
List<User> findAll();
}

编写实现类

package com.atguigu.service;

import com.atguigu.dao.UserDao;
import com.atguigu.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
* @author wh
* @CREATE 2023/5/31 14:55
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;

@Override
public List<User> findAll() {
return userDao.findAll();
}
}

编写controller类

package com.atguigu.controller;

import com.atguigu.pojo.User;
import com.atguigu.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
* @author wh
* @CREATE 2023/5/31 14:57
*/
@RestController
@RequestMapping("/user")
public class UserController {

@Autowired
private UserService userService;
//查询所有
@GetMapping("/findAll")
public List<User> findAll(){

return userService.findAll();
}
}

编写Test测试类,此处创建和启动类JpaApplication同级包com.atguigu,@SpringBootTest会用到

package com.atguigu;

import com.atguigu.dao.UserDao;
import com.atguigu.pojo.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

/**
* @author wh
* @CREATE 2023/5/31 15:00
*/
@RunWith(SpringRunner.class) // 把spring运行起来,因为要用IOC容器 @Autowired
//@SpringBootTest(classes = {JpaApplication.class}) //测试类与启动类包不一致时 需要引入启动类
@SpringBootTest //告诉程序Spring在哪里 默认在当前包(com.atguigu)下去启动类
public class UserJunitTest {


@Autowired
private UserDao userDao;//SpringIOC容器
@Test
public void testFindAll(){
//连接Mysql数据库
List<User> all = userDao.findAll();
for (User user : all) {
System.out.println(user);
}

}
}

此时是run了两次后,第一次执行后在user表手动添加了一行数据1,2,3,4

测试运行UserJunitTest,控制台打印信息

浏览器测试的话只能测试GET,如果开发PUT、POST和DELETE则建议用Postman工具

四. SpringBoot综合案例-用户信息管理系统(应用)

项目描述: 用户信息管理系统是一款应用于用户管理机构的业务系统,主要提供用户信息查询功能,因用户数据是不经常变化的数据,如果这些数据每次都去数据库中进行查询效率比较低,对数据库造成很大的压力,所以用Redis进行缓存优化,提高查询效率,并将项目进行打包部署到本地并运行。

4.2 环境搭建

4.2.1 数据库准备

要先删除springboot数据库(因为上面学习时用过)

create database springboot character set utf8 ;

use springboot ;

CREATE TABLE `tb_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`gender` varchar(5) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`address` varchar(32) DEFAULT NULL,
`qq` varchar(20) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
`username` varchar(20) NOT NULL,
`phone` varchar(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_username_uindex` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

INSERT INTO `tb_user` VALUES (1,'黄蓉','女',38,'桃花岛','212223390222','huangrong222@qq.com','huangrong','15600003333'),(2,'黄老邪','男',58,'湖北省武汉市','212223390','huanglaoxie@qq.com','huanglaoxie','15872320405'),(3,'小龙女','男',18,'湖北省荆门市','212223390','xiaolongnv@qq.com','xiaolongnv','15600004444'),(7,'杨过','男',30,'扬州','212223390','yangguo@qq.com','yangguo','15600005555');

4.2.2 创建项目及包结构

创建项目 springboot_case

4.2.3 导入依赖

<?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.atguigu</groupId>
<artifactId>springboot_case</artifactId>
<version>1.0-SNAPSHOT</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
</parent>

<dependencies>
<!--单元测试启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>

<!--通用mapper启动器依赖-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
<!--JDBC启动器依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--druid启动器依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!--web启动器依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!--spring boot actuator依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<!--编码工具包-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>

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

</dependencies>

<build>
<plugins>
<!--spring boot maven插件 , 可以将项目运行依赖的jar包打到我们的项目中-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

4.2.4 创建启动类

package com.atguigu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import tk.mybatis.spring.annotation.MapperScan;

/**
* @author wh
* @CREATE 2023/5/31 16:52
*/

@SpringBootApplication
@MapperScan(basePackages = "com.atguigu.dao") //是Mybatis的
@EnableTransactionManagement //@Transactional 打开事务
public class caseApplication {
public static void main(String[] args) {
SpringApplication.run(caseApplication.class,args);
}
}

4.3 数据访问层

4.3.1 编写配置文件application.yml

server:
port: 10001
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql:///springboot?useSSL=false #加了?useSSL=false 是因为我这边报错了解决一下
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
mybatis:
type-aliases-package: com.atguigu.pojo

4.3.2 编写实体类User

package com.atguigu.pojo;

import javax.persistence.Entity;
import javax.persistence.Table;
import java.io.Serializable;

/**
* @author wh
* @CREATE 2023/5/31 16:55
*/
@Entity
@Table(name = "tb_user")
public class User implements Serializable { //Serializable序列化
private Integer id;
private String name;
private String gender;
private Integer age;
private String address;
private String qq;
private String email;
private String username;
private String phone;
//set get toString...
}

4.3.3 Mapper接口和映射配置

package com.atguigu.dao;

import com.atguigu.pojo.User;
import tk.mybatis.mapper.common.Mapper;

/**
* @author wh
* @CREATE 2023/5/31 16:57
*/
public interface UserDao extends Mapper<User> {
}

4.4 业务层

4.4.1编写接口

package com.atguigu.service;


import com.atguigu.pojo.User;

import java.util.List;

/**
* @author wh
* @CREATE 2023/5/31 16:59
*/
public interface UserService {

List<User> findAll();

}

4.4.2 编写实现类

package com.atguigu.service;

import com.atguigu.dao.UserDao;
import com.atguigu.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;


/**
* @author wh
* @CREATE 2023/5/31 17:00
*/
@Service
public class UserServiceImpl implements UserService {

@Autowired
private UserDao userDao; //报红属于误判,不用管,接口本身就不写实现类,是由代理生成的

@Override
public List<User> findAll() {
return userDao.selectAll();
}
}

4.5 表现层

4.5.1 引入起步依赖

之前已经引入

<!--Web起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!--编码工具包-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>

4.5.2 新建工具类

package com.atguigu.utils;

import java.io.Serializable;

/**
* @author wh
* @CREATE 2023/5/31 17:05
*/
public class Result implements Serializable {
private boolean status ; //响应状态 true false
private String msg ; // 响应信息
private Object data ; //处理成功的响应数据

public static Result ok(Object data){
Result result = new Result();
result.setStatus(true);
result.setData(data);
return result ;
}

public static Result error(String msg){
Result result = new Result();
result.setStatus(false);
result.setMsg(msg);
return result ;
}

// 生成set get tostring方法
}

4.5.3 编写表现层代码

package com.atguigu.controller;

import com.atguigu.service.UserService;
import com.atguigu.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* @author wh
* @CREATE 2023/5/31 17:03
*/
@RestController
@RequestMapping("/user")
public class UserController {

@Autowired
private UserService userService;
@GetMapping("/findAll")
public Result findAll(){
return Result.ok(userService.findAll());
}
}

4.6 页面展示

resources目录下创建static目录 , 将提供的页面复制进来 , 修改即可 :

  • 页面异步请求的端口和服务器端口一致

  • 页面异步请求访问的路径和对应的表现层控制方法路径要致

  • 页面异步请求参数名称和和对应的表现层控制方法参数一致

修改之后, 访问页面即可 : localhost:10001/list.html

4.7 缓存优化(Redis)

4.7.1 缓存需求

4.7.2 引入起步依赖

<!--springboot整合redis启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

4.7.3 编写配置文件

这里笔者用的192.168.6.100是用虚拟机启的Redis

配置好Redis之后在虚拟机中启Redis:(详情可见本博客另一篇Redis帖子)

redis-server   /root/myredis/redis.conf
spring:
redis: # 配置redis
host: 192.168.6.100
port: 6379

4.7.4 修改业务层实现类代码

package com.atguigu.service;

import com.atguigu.dao.UserDao;
import com.atguigu.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;


import java.util.List;


/**
* @author wh
* @CREATE 2023/5/31 17:00
*/
@Service
public class UserServiceImpl implements UserService {

@Autowired
private UserDao userDao; //属于误判,不用管,接口本身就不写实现类,是由代理生成的
@Autowired
private RedisTemplate redisTemplate;

@Override
public List<User> findAll() {
//1:查询缓存中是否有数据 值类型(String) Hash类型(散列类型) List类型(列表类型) Set类型(集合) ZSet类型(有序集合)
List<User> userList = (List<User>) redisTemplate.opsForValue().get("userList");
if (userList != null && userList.size() >0){
//2:有
System.out.println("缓存中有数据");
}else{
//3:没有 查询DB
userList = userDao.selectAll();
System.out.println("缓存中没有数据");
//4:保存缓存一份
redisTemplate.opsForValue().set("userList",userList);
}
return userDao.selectAll();
}
}

启动caseApplication,打开页面http://localhost:10001/list.html两次

五. SpringBoot其他组件(了解)

5.1 SpringBoot Actuator组件

5.2 SpringBoot Admin组件

六. Spring Boot项目打包部署(应用)

即部署到自己的服务器上

6.1 项目打包

  1. pom.xml中配置Spring Boot项目的maven插件
<build>
<plugins>
<!-- 打jar包时如果不配置该插件,打出来的jar包没有主清单属性 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
  1. 运行maven的打包命令 : package
  1. 打包之前我们需要跳过测试 , 如果不跳过测试那么我们编写的测试类都会被maven自动执行, 可能会出现错误,导致打包不成功
  1. 执行之后可以在控制台看到打包的日志信息, 其中有生成的包的位置

打开指定目录就可以发现有一个jar包存在 , 仔细观察其实我们会发现 , 在target目录下其实会存在二个jar包 , 一个是springboot_02-1.0-SNAPSHOT.jar一个是springboot_02-1.0-SNAPSHOT.jar.original , 那么这两个jar包有什么区别呢?

我们如果是普通项目打包那么就只会得到一个jar包 , 这个jar包中不包含项目的一些依赖jar包

但是我们现在是一个Spring Boot项目 , 我们希望打完的包能够直接运行, 所以项目中就必须包含他的依赖jar包 , 我们之前在pom.xml中配置一个Spring Boot的maven插件可以在普通包的基础上将我们项目的一些运行及依赖信息打进jar包里面 , 打完包之后将原来的普通包改名为xxx.jar.original , 新打的包为xxx.jar .

  1. 简单总结一下 :

• .jar.original 是普通jar包,不包含依赖
• .jar 是可执行jar包,包含了pom中的所有依赖,可以直接用java -jar 命令执行
• 如果是部署,就用.jar , 如果是给别的项目用,就要给.jar.original这个包

把jar包扔到服务器中即可,然后启动

6.2 项目运行

打开命令行运行打出来的包;使用命令:java –jar 包全名

java -jar springboot_case-1.0-SNAPSHOT.jar

打开页面:

http://localhost:10001/list.html

再刷新一次页面:

注意:笔者这里因为之前没有清缓存所以2次都是”缓存中有数据”,如果清了缓存再打开2次页面则会1次无,1次有数据