写在前面
为什么使用 SpringBoot?
- 遵循
约定优于配置
的原则 - 提供
starter POM
,高效包管理 - 简化配置,
无需XML
- 内嵌servlet容器
- 与主流框架
集成简单
。
Spring的缺陷?
-
配置繁琐
- 虽然Spring的组件代码是轻量级的,但它的配置却是重量级的。
- Spring 2.5引入了
基于注解的组件扫描
,这消除了大量针对应用程序自身组件的显式XML配置。 - Spring 3.0引入了
基于Java的配置
,这是一种类型安全的可重构配置方式,可以代替XML。 - 所有这些配置都代表了开发时的损耗。因为在思考Spring特性配置和解决业务问题之间需要进行思维切换,所以编写配置挤占了编写应用程序逻辑的时间。
- 和所有框架一样,Spring实用,但它要求的回报也不少。
-
依赖繁琐
- 项目的依赖管理也是一件耗时耗力的事情。在环境搭建时,需要分析要导入哪些库的坐标,
- 而且还需要分析导入与之有依赖关系的其他库的坐标,
- 一旦选错了依赖的版本,随之而来的不兼容问题就会严重阻碍项目的开发进度。
那么,为什么使用SpringBoot也就再清楚不过了?
- 首先,springboot能够起到快速使用spring的作用,相较于spring的配置繁杂,对依赖的繁琐,一旦选错依赖的版本就会出现兼容等问题阻碍项目的开发进度,
- spring boot支持自动配置,和起步依赖等功能,把这些操作都交由springboot来处理,大大加快了开发的进度,另外,spring boot还内置了Tomcat等多种服务器。
1. SpringBoot概述
SpringBoot提供了一种快速使用Spring的方式
,基于约定优于配置的思想,可以让开发人员不必在配置与逻辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中,从而大大提高了开发的效率,一定程度上缩短了项目周期。
2014年4月,Spring Boot 1.0.0 发布。Spring的顶级项目之一(https://spring.io)。
1.1 SpringBoot快速入门案例
1.1.1 手动搭建SpringBoot
创建Maven项目
,打开 IDEA → \rightarrow → File → \rightarrow → Module → \rightarrow → Maven → \rightarrow → New Module
>
导入SpringBoot起步依赖
定义Controller
创建引导类
启动测试
1.1.2 自动动搭建SpringBoot
自动配置后,我们只需要配置一个controller即可
1.2 小结
- SpringBoot在创建项目时,
使用jar的打包方式
。 - SpringBoot的引导类,是项目入口,
运行main方法
就可以启动项目。 - 使用SpringBoot和Spring构建的项目,业务代码编写方式完全一样。
2. SpringBoot 起步依赖、SpringBoot 配置
2.1 起步依赖
- spring-boot-starter-parent
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
- spring-boot-starter-web
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.1.1 小结
- 在spring-boot-starter-parent中定义了各种
技术的版本信息
,组合了一套最优搭配的技术版本。 - 在各种starter中,定义了
完成该功能需要的坐标合集
,其中大部分版本信息来自于父工程。 - 我们的工程继承parent,引入starter后,通过依赖传递,就可以简单方便获得需要的jar包,并且不会存在版本冲突等问题。
2.2 SpringBoot 配置
2.2.1 配置文件分类
- SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用下面几种类型的文件进行配置
- application.properties
- application.yml
- application.yaml
properties:
server.port=8080
yml:
server:
port: 8080
注意:port:后面有一个空格。
小结
- SpringBoot提供了2种配置文件类型: properteis和yml/yaml
- 默认配置文件名称: application
- 在同—级目录下优先级为: properties
>
yml>
yaml
2.2.2 yaml
YAML全称是YAML Ain't Markup Language
。YAML是一种直观的能够被电脑识别的的数据数据序列化
格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入,比如:C/C++, Ruby, Python, Java, Perl, C#, PHP等。
YML文件是以数据为核心
的,比传统的xml方式更加简洁。YAML文件的扩展名可以使用.yml或者.yaml。
1. xml、properties、yml比较
properties:
server.port=8080
server.address=127.0.0.1
xml:
<server>
<port>8080</port>
<address>127.0.0.1</ address>
</ server>
yml:
server:
port: 8080
address: 127.0.0.1
2. 基本语法
大小写
敏感- 数据值前边
必须有空格
,作为分隔符使用缩进表示层级关系 - 缩进时
不允许使用Tab键
,只允许使用空格(各个系统Tab对应的空格数目可能不同,导致层次混乱)。 - 缩进的
空格数目不重要
,只要相同层级的元素左侧对齐即可 #
表示注释,从这个字符一直到行尾,都会被解析器忽略。
server:
port: 8080
address: 127.0.0.1
name: abc
3. 数据格式
- 对象(map):键值对的集合。
person:
name: zhangsan
age: 20
# 行内写法
person : {name: zhangsan,age: 20}
- 数组:—组按次序排列的值
address:
- beijing
- shanghai
# 行内写法
address: [beijing,shanghai]
- 纯量:单个的、不可再分的值
msgl : 'hello \n world' # 单引忽略转义字符
msg2: "he1lo \n world" # 双引识别转义字符
4. 参数引用
name: lisi
person:
name: ${name} # 引用上边定义的name值
5. 小结
- 配置文件类型
- properties:和以前一样
- yml/yaml:注意空格
- yaml:简洁,以数据为核心
- 基本语法
- 大小写敏感
- 数据值前边必须有空格,作为分隔符
- 使用空格缩进表示层级关系,相同缩进表示同—级
- 数据格式
- 对象
- 数组:使用
-
表示数组每个元素 - 纯量
- 参数引用
${key}
- 基本语法
2.2.3 获取数据
- @Value
- Environment
- @ConfigurationProperties
@RestController
public class HelloController {
@Value("${name}")
private String name;
@Value("${person.name}")
private String name2;
@Value("${person.age}")
private int age;
@Value("${address[0]}")
private String address1;
@Value("${msg1}")
private String msg1;
@Value("${msg2}")
private String msg2;
@Autowired
private Environment env;
@Autowired
private Person person;
@RequestMapping("/hello2")
public String hello2() {
System.out.println(name);
System.out.println(name2);
System.out.println(age);
System.out.println(address1);
System.out.println(msg1);
System.out.println(msg2);
System.out.println("----------------------");
System.out.println(env.getProperty("person.name"));
System.out.println(env.getProperty("address[0]"));
System.out.println("-------------------");
System.out.println(person);
String[] address = person.getAddress();
for (String s : address) {
System.out.println(s);
}
return "hello Spring Boot 222!";
}
@RequestMapping("/hello")
public String hello() {
return "hello Spring Boot 222!";
}
}
控制台访问:localhost:8080/hello2
,打印输出
abc
zhangsan
20
beijing
hello \n world
hello
world
----------------------
zhangsan
beijing
-------------------
Person{name='zhangsan',age=20}
beijing
shanghai
@Component
//配置前缀让其识别 person.name 而不是 name:abc的 name
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private int age;
private String[] address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String[] getAddress() {
return address;
}
public void setAddress(String[] address) {
this.address = address;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2.2.4 proflie
我们在开发Spring Boot应用时,通常同一套程序
会被安装到不同环境,比如:开发
、测试
、生产
等。其中数据库地址
、服务器端口
等配置都不同,如果每次打包时,都要修改配置文件,那么非常麻烦。
profile是用来完成不同环境下,配置动态切换功能的
。
- profile配置方式
- 多profile文件方式:提供多个配置文件,每个代表—种环境。
- application-dev.properties/yml
→
\rightarrow
→
开发环境
- application-test.properties/yml
→
\rightarrow
→
测试环境
- application-pro.properties/yml
→
\rightarrow
→
生产环境
- application-dev.properties/yml
→
\rightarrow
→
- yml多文档方式:
- 在yml中使用
---
分隔不同配置
- 在yml中使用
- 多profile文件方式:提供多个配置文件,每个代表—种环境。
- profile激活方式
- 配置文件:在配置文件中配置
→
\rightarrow
→
spring.profiles.active=dev
- 虚拟机参数:在VM options指定
→
\rightarrow
→
-Dspring.profiles.active=dev
- 命令行参数: java -jar xxx.jar
→
\rightarrow
→
--spring.profiles.active=dev
多profile文件方式
- application-dev.properties
spring.profiles.active=dev
- application-dev.properties
server.port=8081
- application-pro.properties
server.port=8083
- application-test,properties
server.port=8082
yml多文档方式
---
server:
port: 8081
spring:
profiles: dev
---
server:
port: 8082
spring:
profiles: test
---
server:
port: 8083
spring:
profiles: pro
---
spring:
profiles:
active: dev # 表示激活dev
profile激活方式
1. 虚拟机参数
-Dspring.profiles.active=test
2. 命令行参数
--spring.profiles.active=pro
拓展
通过打包,在终端运行jar包的方式启动
1. 打包
2.找到jar包,在目标文件的目录下,按(shlft+右键)打开终端执行下面命令
2.2.5 项目内部配置文件
Springboot程序启动时,会从以下位置加载配置文件:
file:./config/
︰当前项目下的/config目录下file:./
︰当前项目的根目录classpath:/config/
︰classpath的/config目录classpath:/
︰ classpath的根目录
加载顺序为上文的排列顺序,高优先级配置的属性会生效
2.2.6 项目外部配置文件
通过官网查看外部属性加载顺序:
3. SpringBoot 整合其他框架
3.1 SpringBoot 整合Junit
搭建SpringBoot工程
引入start-test起步依赖,已经自动引入
编写UserService测试类(位置在src.main.java下的com.ithema.springboottest)
package com.ithema.springboottest;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public void add(){
System.out.println("add方法执行....");
}
}
编写测试类(位置在src.test.java下的com.ithema.test)
package com.ithema.test;
import com.ithema.springboottest.UserService;
import com.ithema.springboottest.SpringbootTestApplication;
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;
@RunWith(SpringRunner.class)
//如果测试类的包在test中的com.ithema.springboottest和main同名,
//则(classes = SpringbootTestApplication.class)可以不加
@SpringBootTest(classes = SpringbootTestApplication.class)
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void testAdd(){
userService.add();
}
}
3.2 SpringBoot 整合redis
引入redis起步依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置redis相关信息
注入模板
编写测试类
package com.ithema.springboottest;
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.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootRedisTest {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testGet(){
//获取数据
Object o = redisTemplate.boundValueOps("name").get();
System.out.println(o);
}
@Test
public void testSet(){
//存数据
redisTemplate.boundValueOps("name").set("zhangsan");
}
}
3.3 SpringBoot 整合mybatis
引入mybatis起步依赖,添加驱动
<dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<!--<scope>runtime</scope>-->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
编写配置
# application.yml文件内容
# datasource
spring:
datasource:
url: jdbc:mysql:///springboot?serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
# mybatis //mpper文件开发需要添加的Mapper文件的路径
mybatis:
mapper-locations: classpath:mapper/*Mapper.xml # mapper映射文件路径
type-aliases-package: com.itheima.springbootmybatis.domain # 别名
# config-location: # 指定mybatis的核心配置文件
<!--在reoources中创建一个mapper文件夹、编写UserMapper.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.itheima.springbootmybatis.mapper.UserXmlMapper">
<select id="findAll" resultType="user">
select * from t_user
</select>
</mapper>
定义表和实体类
CREATE DATABASE `springboot` ;
USE `springboot`;
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`password` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
insert into `t_user`(`id`,`username`,`password`) values (1,'zhangsan','123'),(2,'lisi','234');
package com.itheima.springbootmybatis.domain;
public class User {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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 "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
编写dao和mapper文件/纯注解开发
import java.util.List;
@Mapper
@Repository
//注解开发
public interface UserMapper {
@Select("select * from t_user")
public List<User> findAll();
}
import java.util.List;
@Mapper
@Repository
//mpper文件开发
public interface UserXmlMapper {
public List<User> findAll();
}
测试
package com.itheima.springbootmybatis;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootMybatisApplicationTests {
@Autowired
private UserMapper userMapper;
@Autowired
private UserXmlMapper userXmlMapper;
@Test
public void testFindAll() {
List<User> list = userMapper.findAll();
System.out.println(list);
}
@Test
public void testFindAll2() {
List<User> list = userXmlMapper.findAll();
System.out.println(list);
}
}