简介
Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化Spring 应用的初始搭建以及开发过程。该框架使用了自动方式来进行配置,减少开发人员定义配置复杂度。(写过都知道,配置有多恶心,至少是把我这个新手恶心坏了)
设计初衷
- 为Spring开发者提供一种,从更快速、体验更好的Spring应用开发方式。
- 开箱即用,同时也可快速扩展,嵌入式的tomcat。
- 绝对没有冗余代码,也无需XML配置。
核心功能
- Spring容器、日志、自动配置AutoCongfiguration、Starters
- web应用的能力:MVC、嵌入式容器
- 数据访问(持久化):关系型数据库、非关系型数据库
- 强大的整合其他技术的能力
- 测试:强悍的应用测试
环境要求
- 必须要使用Java8或 Java 11
- Spring 版本也必须是5.1.8及以上
- Maven 版本要求是3.3及以上。
- Servlet容器版本:Spring Boot应用程序最低支持到Servlet 3.1的容器。
快速开始
步骤
- 使用Spring Initializr创建SpringBoot
- 配置项目信息
- 勾选起步依赖
- 编写三层架构代码
访问http://localhost:8080/hello接口测试
第一步
使用Spring Initializr创建SpringBoot
Default那里是通过Spring官网的模板来创建
第二步
配置项目信息
第三步
勾选起步依赖
第四步
新建完成后,注意留意pom文件。会发现有自动配置的父座标,这也是所有用springboot项目都会带的坐标
<!--父坐标-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
以及自动配置的刚才勾选的相关依赖,比如刚才勾选的web依赖
<!--web 开发的相关依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
编写代码
注意
@SpringBootApplication
注解等于
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
这三个注解,即设定当前类为配置类,开启自动配置,开启包扫描
QuickstartHelloworldApplication类
package com.chayedan.quickstart_helloworld;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class QuickstartHelloworldApplication {
public static void main(String[] args) {
SpringApplication.run(QuickstartHelloworldApplication.class, args);
}
}
HelloController类
package com.chayedan.quickstart_helloworld.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author chayedan666
* @version 1.0
* @className: HelloController
* @description:
* @date: 2020/4/23
*/
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "hello";
}
}
第五步
运行QuickstartHelloworldApplication类,访问http://localhost:8080/hello
相关技巧
热部署
添加热部署支持的依赖坐标
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency>
- 在setting中,compiler中勾选Build Project Automatically
- 快捷键
Shift + Ctrl + Alt + /
打开Maintenance维护,选择Registry(注册表)开启运行时自动编译
不过没什么卵用,因为这个自动编译是看Idea的心情,要编译我jio得我自己动一下手还好点,就当活动筋骨了。
原理分析
依赖管理
进入pom文件,查看spring-boot-starter-parent会发现他还有一个父亲spring-boot-dependencies。也就是说这里来有两层依赖,其中spring-boot-dependencies中用dependencyManagement来管理依赖他的子工程。
starter原理
官方解释
Starters are a set of convenient dependency descriptors that you can include in your application. You get a one-stop shop for all the Spring and related technologies that you need without having to hunt through sample code and copy-paste loads of dependency descriptors. For example, if you want to get started using Spring and JPA for database access, include the spring-boot-starter-data-jpa
dependency in your project.
翻译过来大致就是
Starters是一组方便的依赖项描述符,您可以在应用程序中包括它们。 您可以一站式购买所需的所有Spring和相关技术,而不必搜寻示例代码和依赖描述符的复制粘贴负载。 例如,如果要开始使用Spring和JPA进行数据库访问,请在项目中包括spring-boot-starter-data-jpa依赖项。
用大白话来理解就是依赖关系的封装,spring官方将项目需要的各种包打包封装好了。把很多常用开发框架都打包成一个一个模块,这样,在你需要用的时候,就选择什么模块。比如说,我们需要开发web项目,在新建工程时,就勾选web。这样选择后,就如依赖管理原理所述,官方会在spring-boot-dependencies中用dependencyManagement来管理依赖,不会发生依赖冲突的问题。
自动配置原理
每个Starter基本都会有个AutoConfiguration的Jar包,每个AutoConfiguration定义了约定的默认配置。当然,需要更改自动配置时也可以更改配置。
自动配置的相关文件在启动类的@SpringBootApplication中追踪。
@EnableAutoConfiguration
@Import({AutoConfigurationImportSelector.class})
搜索spring.factories
可以在里面查看很多相关配置
但不建议查看,官方给你封装好了又不是给你看的。。。。
需要用的话自己配置
配置文件写法
约定优于配置(convention over configuration)
在写配置文件之前,我们需要明白这句话是什么意思。
按照wiki上所述约定优于配置,也称作按约定编程,是一种软件设计范式,旨在减少软件开发人员需做决定的数量,获得简单的好处,而又不失灵活性。
简单点来说,就是我们常说的约定俗成。
打个比方,我们都习惯性地在命名类的时候,开头大写,并且在下一个单词的时候开头的字母大写来区分单词。但在Java的命名中,并没有规定必须是这样。你类名全小写照样能用,照样能过编译。但为什么几乎所有人写代码都这样来命名了,这就是我们每个人之间的约定。
SpringBoot是基于约定的,所以很多配置都有默认值。如果想修改默认配置,可以使用application.properties
或application.yml(application.yaml)
自定义配置。SpringBoot默认从Resource目录加载自定义配置文件。application.properties是键值对类型,这里就不多介绍了,主要讲yml文件这种全新的(对我来说)配置格式的写法。
普通的书写方式
key: value
注意,冒号后面有空格。
# yaml
user: chayedan
注意,这里的username会出现一个错误。如果赋值给变量的话,变量的值可能不会是你写在这里的值,会是你电脑的用户名。
配置对象数据
person:
name: chayedan
age: 18
address: beijing
#或者
person: {name: chayedan,age: 18,address: beijing}
配置集合,数组数据语法
数组元素每一个元素开头要用-
来书写(一横后面有一个空格)
# 数组,这里的名字对应你对象中的变量名
city:
- beijing
- tianjin
- shanghai
- chongqing
#集合中的元素是对象形式,这里的名字对应你对象中的变量名
student:
- name: zhangsan
age: 1
score: 50
- name: lisi
age: 2
score: 80
- name: wangwu
age: 3
score: 100
SpringBoot跟我们约定好的配置
https://docs.spring.io/spring-boot/docs/2.2.6.RELEASE/reference/html/appendix-application-properties.html#server-properties
如果你习惯了properties文件的写法,又不想改,但又想要用yml的写法,可以网上搜索properties文件转换为yml文件
配置文件属性注入Bean
注解@Value映射
@Value("${user}")
private String user;
注解@ConfigurationProperties映射
通过注解@ConfigurationProperties(prefix=''配置文件中的key的前缀")
可以将配置文件中的配置自动与实体进行映射。
注1:使用@ConfigurationProperties方式必须提供Setter方法,使用@Value注解不需要Setter方法。
注2:在某些版本可能需要在pom中添加配置文件处理器
<!--配置文件处理器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
SpringBoot与常用技术集成
集成MyBatis
创建工程
Web选项中勾选Spring Web
,SQL选项中勾选MySQL Driver
和MyBatis Framework
配置数据库连接信息
在application.properties中添加数据库连接信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=pw
spring.datasource.url=jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
编写三层代码
domain,controller,service很常规。
需要注意的是dao层
使用@Mapper标记该类是一个Mapper接口,可以被SpringBoot自动扫描
package com.chayedan.mapper;
import com.chayedan.domain.User;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
@Mapper // 表明当前接口是一个Mapper,被MyBatis框架扫描
public interface UserMapper {
List<User> findAll();
User findById(Integer id);
void save(User user);
void update(User user);
void delete(Integer id);
}
另外将Mapper映射文件我放在了src/main/resources/mapper
路径下
在配置文件中添加MyBatis信息
在application.properties中添加MyBatis信息
# 配置扫描实体类
mybatis.mapper-locations=classpath:mapper/*Mapper.xml
# 配置扫描UserMapper.xml
mybatis.type-aliases-package=com.chayedan.domain
写路径的小技巧
打开target文件夹,这就是编译后的文件组成。照着写就完事了
集成Redis
添加starter依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
添加Redis配置
在application.properties
中配置redis端口、地址。但其实可以不用配置,因为默认就是本机和6379。
# redis配置
spring.redis.host=localhost
spring.redis.port=6379
注入RedisTemplate测试一下
注意一下RedisTemplate,以前没用过这个来操作redis。从导入的包来看,这个是Spring自带的
import org.springframework.data.redis.core.RedisTemplate;
测试代码
@Autowired
RedisTemplate redisTemplate;
/**
* 查询所有
* @return
*/
@RequestMapping("/findAll")
public String findAll() throws JsonProcessingException {
String userAllCache = (String) redisTemplate.boundValueOps("user.findAll").get();
//第一次查询,去缓存中取数据
if(StringUtils.isEmpty(userAllCache)){
//如果没有
//从数据库取
List<User> allUser = userService.findAll();
//把用户集合数据转换为json字符串
ObjectMapper jsonFormat = new ObjectMapper();
userAllCache = jsonFormat.writeValueAsString(allUser);
//缓存redis
redisTemplate.boundValueOps("user.findAll").set(userAllCache);
System.out.println("-------------从数据库获取数据-------------");
//返回用户数据
return userAllCache;
}else {
//如果有,直接返回用户数据
System.out.println("-------------从Redis缓存获取数据-------------");
return userAllCache;
}
}
集成定时器
开启定时器注解
@EnableScheduling//开启定时器
@SpringBootApplication
@EnableScheduling//开启定时器
public class SpringbootMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMybatisApplication.class, args);
}
}
编写定时器类
方法上注解了@Scheduled
的方法就是定时器,当然别忘了把类注入Spring容器
@Component
public class Timer {
// @Scheduled(cron = "0/2 * * * * ?")
/**
* initialDelay = 项目启动后,多久执行,fixedRate = 固定的频率执行
* initialDelay = 项目启动后, 多久执行,fixedDelay = 上一个任务执行完成,多久之后执行下一个任务
*/
// @Scheduled(initialDelay = 1000,fixedRate = 2000)
@Scheduled(initialDelay = 1000,fixedDelay = 2000)
public void mytask(){
System.out.println("当前系统时间:"+new Date());
}
}
cron表达式生成器
RestTemplate
RestTemplate是Rest的HTTP客户端模板工具类,对基于Http的客户端进行封装,并且实现对象与JSON的序列化与反序列化
使用方法
配置RestTemplate的对象Bean到Spring容器中。随便写一个即可
@Configuration // 表明是个配置类 跟@Component效果一样的
public class MyConfiguration {
@Bean // 将方法返回的对象注入到Spring容器中
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
然后进行调用
@RunWith(SpringRunner.class)
@SpringBootTest//代表当前的类是测试类
public class Tests {
@Autowired
RestTemplate restTemplate;
@Test
public void testRestTemplate() {
/**
* 两个参数,
* 第一个参数:请求地址
* 第二个参数:反序列化的类型
*/
String html = restTemplate.getForObject("http://baidu.com", String.class);
System.out.println(html);
}
}
通过RestTemplate的getForObject()方法,传递url地址及实体类的字节码。RestTemplate会自动发起请求,接收响应,并且对结果进行反序列化。
打包部署
启动方式有两种,一种是打成jar直接执行,另一种是打包成war包放到Tomcat服务下,启动Tomcat。因为本身就自带了tomcat在里面。推荐打包就打jar包(默认也是jar包)
直接maven旁边的package打包即可。
另外一点是如果要跳过test文件夹,需要在pom中加上
<!-- maven方式跳过maven test 相当于 mvn package -Dmaven.test.skip=true -->
<maven.test.skip>true</maven.test.skip>
或者在mvn命令后添加参数
mvn package -Dmaven.test.skip=true
在命令行输入
java -jar jar包
即可完成启动
如果用命令行打包会在运行时可能会出现
找不到或无法加载主类
的错误。解决的方法建议google