文章目录
Spring Boot
1、SpringBoot 概述
官网是这样介绍 SpringBoot 的:《https://spring.io/projects/spring-boot》
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”.
We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need very little Spring configuration.
-
Spring 从 2003 年到 2020 年蓬勃发展,但是里面所写的东西都是配置文件,正因为其集成很多框架或者一些大项目会导致整个程序和项目十分的臃肿。
-
Spring Boot(英文中是“引导”的意思),是用来简化 Spring 应用的搭建到开发的过程。
-
SpringBoot 的出现是为了简化配置文件,就好像 Spring 的升级版,原来很多东西需要手动配置,现在都可自动配置!
-
还有一点,约定优于配置 ,基于这种软件设计范式,使得 SpringBoot 在快速开发应用和微服务架构实践中得到广泛应用。
2、HelloWorld 实战
2.1 使用 IDEA 创建 SpringBoot 程序
1、开始新建一个springboot项目,选中Spring Initializr,选中默认它会从网站上下载,还有一点就是 jdk的要求要1.8之上;
2、然后进行下一步,配置项目名和包名,其他都是系统根据自己电脑环境默认配置,若有错的话可以进行相应的修改;
3、继续下一步,注意这里的版本号,我们默认选择最新的 2.2.5 就好,由于我们需要构建一个 web 项目通过访问 Controller 来验证项目是否成功搭建,所以这里添加 web 包;并且选择了 Spring Web 相当于帮你自动配置好了 Spring、SpringMVC 和 Tomcat;
4、然后 Next,选择项目的初始化路径,点击 Finish 完成创建。
5、新建成功之后,接着会自动下载相应的 jar 包,SpringBoot 的方便之处就体现出来了,会节省很多代码。
2.2 编写测试程序
测试程序一定要在 SpringBoot 主启动类的同级或者子集目录下,新建包,否则无法识别!
在主启动类的同级或者子集目录下创建一个 controller 包,并且在这个包下新建一个 Hellocontroller 类;
编写测试代码:
package com.su.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "Hello,World!";
}
}
@RestController 和 @RequestMapping 注解是来自 SpringMVC 的注解,它们不是 SpringBoot 的特定部分。
@RestController:提供实现了REST API,可以服务 JSON,XML 或者其他。这里是以 String 的形式渲染出结果
@RequestMapping:提供路由信息,”/“路径的 HTTP Request 都会被映射到 hello 方法进行处理。
启动主启动类:
@SpringBootApplication:Spring Boot 应用的标识
Application 很简单,一个 main 函数作为主入口。
SpringApplication 引导应用,并将 Application 本身作为参数传递给 run 方法。
具体 run 方法会启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件。
2.3 测试结果
访问测试;http://localhost:8080/hello
3、 自定义启动 Logo
1、我们在 resource 目录下新建一个 banner.txt
,在这里面写入自己的 banner 即可;
2、在线网站生成 banner :https://www.bootschool.net/ascii
3、启动测试看效果;
4、SpringBoot 原理
4.1 程序启动
新建的一个 SpringBoot 项目中,都有一个主启动类:
package com.su;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
// 只要标注了他就代表是SpringBoot的应用
@SpringBootApplication
public class SpringbootHelloApplication {
// 你以为启动一个方法,没想到开启了一个服务
public static void main(String[] args) {
// Spring的启动类,通过run方法来具体执行
SpringApplication.run(SpringbootHelloApplication.class, args);
}
}
启动需求:
一个注解:@SpringBootApplication
一个类:SpringApplication
4.2 依赖配置
1、父依赖
<!-- 父依赖
spring-boot-starter-xx 启动类
-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- 点进源码后发现 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
2、父依赖作用分析:
- 自动帮你管理依赖,里面包含了几乎常用的所有依赖,如果你需要的依赖在这里面有,你就不要配置了,如果没有再配置;
- 插件和资源过滤的自动管理;
3、启动器
<!--依赖-->
<!--在这里写的依赖都不需要版本号,只要在父依赖中有!-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--
spring-boot-starter-xx 场景启动器;
导入对应场景所需要的类会自动帮你导入封装了这个场景所需要需要的依赖
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
官网有所有的启动器:https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/html/using-spring-boot.html#using-boot
5、SpringBoot 配置文件
所有的配置都可以在配置文件中配置。
配置文件格式:
application*.yml
application*.yaml
application*.properties
SpringBoot 中推荐使用 properties 或者 yaml 文件来完成配置,但是对于较复杂的数据结构来说,yaml 又远远优于 properties 。
5.1 properties
properties 是我们传统的配置文件 key = value(键值对);
environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App
my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com
5.2 yaml
environments:
dev:
url: http://dev.bar.com
name: Developer Setup
prod:
url: http://foo.bar.com
name: My Cool App
my:
servers:
- dev.bar.com
- foo.bar.com
5.3 对比
可以明显的看到,在处理层级关系的时候,properties 需要使用大量的路径来描述层级(或者属性),比如 environments.dev.url 和 environments.dev.name。
其次,对于较为复杂的结构,比如数组(my.servers),写起来更为复杂。而对应的YAML格式文件就简单很多。
需要注意的是:yaml url:后边需要空格,否则将会解析错误,如果不确定自己是否又空格,可以看 url 是否变色,如果不变色(黑色)就说明缺少空格。
6、集成 MyBatis
数据访问层;MyBatis 所有的包都是自己的,所以要导入自己的依赖
6.1 导入驱动和依赖
<!-- 这是自定义的包 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!-- mysql 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- 导入 lombok 方便实体类方法调用 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- 使用 xml 的话,需要过滤,springboot 只过滤了 yaml -->
<build>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
6.2 生成数据库
CREATE DATABASE `mybatis`
USE `mybatis`;
CREATE TABLE `user` (
`id` int(20) NOT NULL,
`name` varchar(30) DEFAULT NULL,
`pwd` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
INSERT INTO `user`(`id`,`name`,`pwd`)
VALUES (1,'周丹','123456'),(2,'周颖','zxcvbn'),(3,'赵日天','123456');
生成数据表为:
6.3 编写配置文件
二选一;
编写配置文件 application.properties
# 集成 Mybatis
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# mysql 5 com.mysql.jdbc.Driver
# mysql 8 com.mysql.cj.jdbc.Driver 必须要在 url 连接中编写时区serverTimezone
# 解决浏览器乱码问题
spring.http.encoding.force=true
spring.http.encoding.charset=UTF-8
编写配置文件 application.yaml
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
type-aliases-package: com.su.pojo
mapper-locations: classpath:com/su/mapper/*.xml
6.4 测试数据源
package com.su;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
@SpringBootTest
class SpringbootHelloApplicationTests {
// 自动导入数据源
@Autowired
private DataSource dataSource;
@Test
void contextLoads() throws SQLException {
// 查看默认数据源 class com.zaxxer.hikari.HikariDataSource
System.out.println(dataSource.getClass());
// connection
Connection connection = dataSource.getConnection();
System.out.println(connection);
// 关闭
connection.close();
}
}
SpringBoot 目前默认的是 数据源 class com.zaxxer.hikari.HikariDataSource
6.5 编写实体类
package com.su.pojo;
import lombok.Data;
@Data
public class User {
private int id;
private String name;
private String pwd;
}
6.6 编写 Mapper 接口
package com.su.mapper;
import com.su.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository // 代表持久层
public interface UserMapper {
// 使用注解
// @Select("select * from user")
List<User> getUserList();
}
这里加的 @Mapper 是 MyBatis 的备注,目的是为了让 spring 能够根据 xml 和这个接口动态生成这个接口的实现。加 @Repository,就是 spring 生成一个 bean,自动注入 service 的相关引用中,表示持久层。
使用 XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.su.mapper.UserMapper">
<select id="getUserList" resultType="User">
select * from user;
</select>
</mapper>
6.7 编写 Controller 测试
package com.su.controller;
import com.su.mapper.UserMapper;
import com.su.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Scanner;
@RestController
public class MyBatisComtroller {
@Autowired
private UserMapper userMapper;
@RequestMapping("/test")
public List<User> getUserList(){
List<User> userLists = userMapper.getUserList();
return userLists;
}
}
@RestController 是 @Responsebody 和 @Controller 两个注解的合体,一般就拿来直接传 json 数据。 为什么可以直接传个对象过去呢?这是因为 springboot 内置了 jackson 模块。
6.8 测试结果
启动主启动类:
package com.su;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootHelloApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootHelloApplication.class, args);
}
}
访问测试;http://localhost:8080/test
浏览器结果:
7、开发 web 应用
7.1 资源存放目录说明:
目录 | 说明 |
---|---|
static | 静态资源 |
templates | 页面,templates只能通过 controller来访问 |
resources | 存放资源文件 |
public | SpringBoot 源码中找到的,静态资源公共的可以放在这里 |
7.2 Thymeleaf
使用Thymeleaf ,导入静态资源模板使用 html 编写页面
1、导入对应的 maven 依赖
<!-- thymeleaf依赖,如果要编写页面一定需要这个依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2、编写 html 页面放到 templates 目录下
3、使用 controller 进行跳转
package com.su.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.ArrayList;
import java.util.Arrays;
@Controller
public class IndexController {
@RequestMapping("/")
public String index() {
System.out.println("1111");
return "index";
}
@RequestMapping("/user/index")
public String userIndex() {
System.out.println("2222");
return "user/index";
}
@RequestMapping("user/list/list")
public String userListList() {
System.out.println("3333");
return "user/list/list";
}
}
4、启动项目请求测试,看是否可以跳转 html 页面!
7.3 Thymeleaf 值传递
1、在后端方法使用 Model 传递值;
package com.su.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.ArrayList;
import java.util.Arrays;
@Controller
public class IndexController {
@RequestMapping("/test")
public String test(Model model) {
model.addAttribute("msg", "hello,String");
model.addAttribute("users", Arrays.asList("123", "456"));
return "test";
}
}
2、在前端使用 th:xxx 去接收后端传递值,注意:一定要导入头文件约束
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- 普通取值 -->
<h1 th:text="${msg}"></h1>
<hr>
<!-- 行内写法 -->
<!--<h3 th:each="user:${users}" >[[${user}]]</h3>-->
<h3 th:each="user:${users}" th:text="${user}"></h3>
</body>
</html>
3、访问:http://localhost:8080/test , 浏览器结果如下: