01、SpringBoot:概述
1.1 SpringBoot是什么?
SpringBoot是搭建应用的脚手架,由Spring公司的核心团队在2013年开始研发、2014年4月发布第一个版本的全新开源的轻量级框架。它基于Spring4.0设计,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。另外SpringBoot通过集成大量的框架使得依赖包的版本冲突等问题得到了很好的解决。
官方对SpringBoot的介绍:
-
Spring Boot使您可以轻松地创建独立的、生产级的、基于Spring的应用程序,您可以“立即运行”。
-
我们对Spring平台和第三方库有一个独到的见解,这样您就可以从最少的麻烦开始了。大多数Spring引导应用程序只需要很少的Spring配置。
SpringBoot的核心思想:【约定优于配置】
1.2 SpringBoot解决什么?
-
复杂的配置
项目各种配置其实是开发时的损耗, 因为在思考 Spring 特性配置和解决业务问题之间需要进行思维切换,所以写配置挤占了写应用程序逻辑的时间。
-
一个混乱的依赖管理
项目的依赖管理也是件吃力不讨好的事情。决定项目里要用哪些库就已经够让人头痛的了,你还要知道这些库的哪个版本和其他库不会有冲突,这难题实在太棘手。并且,依赖管理也是一种损耗,添加依赖不是写应用程序代码。一旦选错了依赖的版本,随之而来的不兼容问题毫无疑问会是生产力杀手。
1.3 SpringBoot的特点
-
快速创建独立的Spring应用。
-
提供固定的启动器依赖(启动器即Spring Boot提供的一个jar包)去简化组件配置,通过自己设置参数(.properties或.yml的配置文件),实现开箱即用(即快速使用)的效果。
-
自动配置Spring和其它有需要的第三方依赖。
-
提供了一些大型项目中常见的非功能性特性,如内嵌服务器(如tomcat、jetty、undertow)、安全、指标,健康检测、外部化配置等。
-
无需 XML 配置。
02、SpringBoot:搭建测试工程
1、创建maven工程
2、配置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>
<!-- 1. 配置父级(作用:依赖版本锁定) -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<groupId>cn.it</groupId>
<artifactId>springboot-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 配置全局属性 -->
<properties>
<!-- 2. 覆盖父级属性(jdk版本) -->
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- 3. 配置web启动器(作用:自动整合SpringMVC、jackson、内嵌tomcat) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
3、编写启动类
启动类就是带 @SpringBootApplication 注解的普通Java类【是运行SpringBoot项目的入口类】
package cn.it;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/** SpringBoot启动类 */
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args){
// 运行Spring应用 (一个run方法就可以运行web项目)
SpringApplication.run(DemoApplication.class, args);
}
}
4、编写Controller
@SpringBootApplication已经有默认的包扫描【默认为启动类的包名】,这样同级或下级都可扫描。
package cn.it.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class QuickController {
@GetMapping("/quick")
public String quick(){
return "SpringBoot 从入门到精通!!";
}
}
03、关闭banner横幅
方式一:
/** SpringBoot启动类 */
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args){
// 运行Spring应用 (一个run方法就可以运行web项目)
//SpringApplication.run(DemoApplication.class, args);
SpringApplication springApplication = new SpringApplication(DemoApplication.class);
// 设置banner为关闭模式
springApplication.setBannerMode(Banner.Mode.OFF);
springApplication.run(args);
}
}
方式二:
需要在resource目录下,提供application.properties属性文件,spring boot默认加载
# 设置banner模式为关闭
spring.main.banner-mode=off
04、SpringBoot:热部署配置
概念
热部署就是正在运行状态的应用,修改了他的源码之后,在不重新启动的情况下能够自动把增量内容编译并部署到服务器上,使得修改立即生效。热部署为了解决的问题有两个, 一是在开发的时候,修改代码后不需要重启应用就能看到效果,大大提升开发效率;二是生产上运行的程序,可以在不停止运行的情况下进行升级,不影响用户使用。
配置步骤
引入热部署依赖
<!-- 热部署配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
idea的额外配置
注意: 改完这些设置信息后,idea需要重启,才有效果!
05、SpringBoot:起步依赖原理
依赖过程:
-
我们的项目springboot-demo需配置起步依赖
- spring-boot-starter-parent项目环境属性锁定
- spring-boot-dependencies依赖版本锁定
我们的项目继承spring-boot-starter-parent父级的作用
-
可以继承到父级的项目环境属性
-
可以继承到父级的全部依赖锁定
06、SpringBoot:启动器&自动配置
使用SpringBoot之后,整合SpringMVC的WEB工程开发,变的无比简单,那些繁杂的配置都消失不见了,这是如何做到的?
6.1 启动器介绍
-
Spring Boot提供的启动器
Spring Boot启动器的作用
-
导入一个启动器它会把整合这个框架或模块的依赖全部导入。
-
使得自动配置生效。
6.2 自动配置原理
- 一切魔力的开始,来自启动类:
-
特别的两个地方:
1、@SpringBootApplication 【重点】
2、SpringApplication.run() 运行spring应用(创建spring容器)
-
1、@SpringBootApplication 相当于三个注解的组合
-
@SpringBootConfiguration 【作用: 定义配置类】
-
@EnableAutoConfiguration 【作用: 启用自动配置】
注解
@EnableAutoConfiguration
,告诉SpringBoot基于你所添加的依赖,去“猜测”你想要如何配置Spring。比如我们引入了spring-boot-starter-web
,而这个启动器中帮我们添加了tomcat
、SpringMVC
的依赖。此时自动配置就知道你是要开发一个web应用,所以就帮你完成了web及SpringMVC的默认配置了! -
@ComponentScan 【作用: 组件扫描】
配置组件扫描的指令。提供了类似与
<context:component-scan>
标签的作用通过basePackageClasses或者basePackages属性来指定要扫描的包。如果没有指定这些属性,那么将默认扫描启动类所在包及子包
-
-
2、自动配置实现流程
-
SpringApplication在运行Spring应用时,是通过SpringFactoriesLoader的loadSpringFactories()方法,加载一些资源文件
- META-INF/spring.factories工厂配置文件
- 这个key所对应的值,就是所有的自动配置
可以在当前的jar包中找到这些自动配置类:
每个包都有一个XxxAutoConfiguration配置类,都是一个基于纯注解的配置类,是某个框架整合的代码。
该自动配置类中指定了一些默认属性,在该包下有一个XxxProperties属性类:
6.3 配置属性流程
配置步骤
-
第一步:配置一个自动配置类的属性,先到spring-boot-autoconfigure-2.1.6.RELEASE.jar找到对应的模块。
- 第二步:如果该自动配置类有可以配置的属性,那么对应的整合模块中一定有一个XxxProperties属性类,在里面找可以配置的属性。
- 第三步:在resources目录下的application.properties或application.yml文件里面可以修改XxxProperties类中默认的属性。
修改resources目录下的application.properties属性文件:
# 设置tomcat端口号
server.port=9001
# 设置项目的访问路径
server.servlet.context-path=/test
yml配置
yaml文件介绍
-
YML文件格式是YAML(YAML Aint Markup Language)编写的文件格式,YAML是一种层级树键值对格式文件,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入,比如: C/C++, Ruby, Python, Java, Perl, C#, PHP等。YML文件是以数据为核心的,比传统的xml方式更加简洁。
-
YML文件的扩展名可以使用.yml或者.yaml。
核心配置
在resources目录下,新建application.yml:
# 注意: 冒号后面必须有空格
# 覆盖自动配置类的默认属性
server:
port: 9002
servlet:
contextPath: /# 定义自已项目中需要的属性
# 标量类型
my:
host: 127.0.0.1
port: 3306# 对象类型
user:
name: 小华华
age: 18
sex: 男# 数组类型
address:
- 天河九巷
- 天河八巷
- 天河十巷# 对象数组类型
users:
- name: 李小三
age: 18
sex: 女
- name: 李小一
age: 20
sex: 男
注意
当application.properties与application.yml两个文件同时存在时,当属性名相同时application.properties中的属性会 覆盖 application.yml中的属性,不相同属性就取并集
6.4 总结
Spring Boot自动配置原理:
-
SpringApplication会寻找 META-INF/spring.factories 文件,读取其中以EnableAutoConfiguration 为key的所有类的名称, 这些类就是提前写好的自动配置类。
-
这些类都声明了@Configuration注解,并且通过@Bean注解提前配置了该组件需要的一切实例。
-
这些配置类不一定全部生效,因为有@ConditionalOn注解,满足一定条件才会生效。
-
我们可以通过配置application.yml或application.properties文件,来覆盖自动配置中的默认属性。
7.SpringBoot:访问配置文件
方式一
@Value: 基本数据类型和String
@RestController
public class PropControlle1 {
@Value("${my.host}")
private String host;
@Value("${my.port}")
private int port;
private User user;
private String[] address;
private List<User> users;
@GetMapping("/test1")
public String test1(){
System.out.println("======test1=======");
System.out.println("host = " + host);
System.out.println("port = " + port);
System.out.println("user = " + user);
System.out.println("address = " + Arrays.toString(address));
System.out.println("users = " + users);
return "test1方法,访问成功!";
}
}
方式二
@ConfigurationProperties
* 条件:1、必须在Bean当中使用;2、必须提供set方法
@RestController
@ConfigurationProperties(prefix = "my")
public class PropController2 {
private String host;
private int port;
private User user;
private String[] address;
private List<User> users;
@GetMapping("/test2")
public String test2(){
System.out.println("======test2=======");
System.out.println("host = " + host);
System.out.println("port = " + port);
System.out.println("user = " + user);
System.out.println("address = " + Arrays.toString(address));
System.out.println("users = " + users);
return "test2方法,访问成功!";
}
/** 注入的属性必须提供setter方法 */
public void setHost(String host) {
this.host = host;
}
public void setPort(int port) {
this.port = port;
}
public void setUser(User user) {
this.user = user;
}
public void setAddress(String[] address) {
this.address = address;
}
public void setUsers(List<User> users) {
this.users = users;
}
}
方式三
将需要注入的属性定义成一个属性类,当用到的时候 需要 启用配置属性。这样做属性类就可以重复使用。
-
@ConfigurationProperties: 配置属性
-
@EnableConfigurationProperties(UserProperties.class): 启用配置属性(创建Bean)
定义属性类:
@ConfigurationProperties(prefix = "my")
public class UserProperties {
private String host;
private int port;
private User user;
private String[] address;
private List<User> users;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String[] getAddress() {
return address;
}
public void setAddress(String[] address) {
this.address = address;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
}
启用配置属性:
@RestController
@EnableConfigurationProperties(UserProperties.class)
public class PropController3 {
@Autowired(required = false)
private UserProperties userProperties;
@GetMapping("/test3")
public String test3(){
System.out.println("======test3======");
System.out.println(userProperties.getHost());
System.out.println(userProperties.getPort());
System.out.println(userProperties.getUser());
System.out.println(userProperties.getAddress());
System.out.println(userProperties.getUsers());
return "test3方法,访问成功!";
}
}