文章目录
一、SpringBoot基础
1. 什么是SpringBoot?
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 minimal Spring configuration.
使用SpringBoot可以轻松地创建独立的、生产级别的Spring应用程序,并且可以快速运行它们。
SpringBoot具有一套基于Spring平台和第三方库的固化视图,因此可以做最小化配置来使用。大部分SpringBoot应用仅需少量配置即可。
好吧,其实设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。
2. SpringBoot的特性
- 创建独立的Spring应用
- 直接嵌入Tomcat、Jetty、Undertow等Web容器(无需部署WAR文件)
- 提供“starter”依赖,简化构建配置
- 条件满足时自动装配Spring或第三方库
- 提供运维(Production-Ready)特性,如指标信息(Metrics)、健康检查及外部化配置
- 无代码生成,不需要XML配置
3. SpringBoot运行环境
SpringBoot 2.0基于Spring Framework 5.0开发,因此java环境同Spring Framework5.0要求一致,最低版本为Java 8。
由于SpringBoot采用模块化设计,它的模块类库管理依赖于Apache Maven,要求maven版本为3.2或更高。
4. SpringBoot应用
SpringBoot应用分为Web应用和非Web应用(服务提供、调度任务、信息处理等场景)。Web应用有两种:Servlet容器实现、Reactive Web容器实现。
支持reactive编程的数据库只有MongoDB、redis、Cassandra、Couchbase。
5. 什么是微服务
贴一个链接:微服务入门
二、 创建一个SpringBoot项目
1. 访问http://start.spring.io来创建项目
点击GENRATE生成ZIP,解压后使用IDEA或eclipse导入项目。
2. 使用IDEA创建(同样基于上方的模板)
File -> new -> project
选择依赖
3. 项目结构
我添加了一个Spring web,生成后的项目结构如下:
(1).idea
使用IDEA创建项目时,会自动生成 .idea文件夹,用来存放项目的配置信息,包括版本控制信息、历史记录等等。
(2).mvn、mvnw和mvnw.cmd
Maven Wrapper文件包括 .mvn 目录、执行脚本 mvnw 和 mvnw.cmd,这些文件源于GitHub工程。
- .mvn/wrapper/maven-wrapper.jar: 该文件由脚本引导,用于从Maven官方下载Maven二进制文件。
- .mvn/wrapper/maven-wrapper.properties: 该文件定义了文件下载的URL。
- mvnw和mvnw.cmd: 两个文件均可引导maven-wrapper.jar下载maven二进制文件。前者用于Linux平台,后者工作于Windows系统。
(3)application.properties
是SpringBoot默认的应用外部配置文件,可以配置Web服务器端口、数据库等。
(4)DemoApplicationTests.java
SpringBoot应用的模板JUnit测试文件,名称不确定,提供了SpringBoot集成的测试基本模式。
(5)DemoApplication.java
引导类Java源码,主程序类
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@SpringBootApplication:该注解是SpringBoot的主配置类,SpringBoot会运行该注解存在的类中的main方法来启动SpringBoot应用程序。
// @SpringBootApplication注解的组合注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
- @SpringBootConfiguration:SpringBoot的配置注解,底层 @Configuration(spring定义) -> @Component组件
- @EnableAutoConfiguration:开启自动配置;由SpringBoot来帮我们自动配置。
-> @AutoConfigurationPackage : 自动配置包
@Import({AutoConfigurationImportSelector.class}):Spring定义的注解,给容器中导入一个组件。
自动配置:扫描主类所在包下面所有子包内的全部组件。
(6)pom.xml
主pom文件
<?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 https://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.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
① 父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- 他的父项目是spring-boot-dependencies -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.0.RELEASE</version>
</parent>
进去spring-boot-dependencies看一下内容:
<properties>
<activemq.version>5.15.12</activemq.version>
<antlr2.version>2.7.7</antlr2.version>
<appengine-sdk.version>1.9.80</appengine-sdk.version>
<artemis.version>2.12.0</artemis.version>
<aspectj.version>1.9.5</aspectj.version>
<assertj.version>3.16.1</assertj.version>
<atomikos.version>4.0.6</atomikos.version>
<awaitility.version>4.0.2</awaitility.version>
<bitronix.version>2.1.4</bitronix.version>
<build-helper-maven-plugin.version>3.1.0</build-helper-maven-plugin.version>
<byte-buddy.version>1.10.10</byte-buddy.version>
<caffeine.version>2.8.2</caffeine.version>
<cassandra-driver.version>4.6.1</cassandra-driver.version>
<classmate.version>1.5.1</classmate.version>
<commons-codec.version>1.14</commons-codec.version>
...
</properties>
spring-boot-dependencies来真正管理SpringBoot应用里面全部依赖版本。也就是我们在项目中导入spring-boot-dependencies已经定义版本的依赖默认不需要填写版本。
②导入的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring-boot-starter-web的pom:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.3.0.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>2.3.0.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.3.0.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<scope>compile</scope>
</dependency>
也就是说它帮我们导入了web模块正常运行所依赖的组件。
SpringBoot将所有的功能场景全部抽取,做成一个个的starter,当我们需要时在项目里引用相关的starter的依赖即可。
三、 配置文件
1. 简介
上面生成项目时会有一个文件:application.properties,那么SpringBoot使用一个全局配置文件,在配置文件中我们可以对一些默认值进行修改,比如端口号等:
- application.properties
- application.yml
这两种配置文件的名字是固定的,其中,yml是YAML(YAML Ain’t MarkUp Language)语言。
在resources文件夹下新建文件:application.yml
yml和properties、xml的区别:
# .properties
server.port = 8080
server.error.path = /error
#.yml
server:
port: 8080
error:
path: /error
<!-- xml -->
<server>
<port>8080</port>
</server>
2. yml语法
key: value(以空格间隔)
以空格缩进控制层级,即:对齐的一列为一层级。
server:
port: 8080
path: /hello
spring:
application:
name: demo
属性和值区分大小写
‘#’ 代表注释
‘~’ 表示 ‘null’
数组:用 ‘-’ 来表示其中一个元素
person:
- WangWu
- LiSan
- Tom
3. yml实例1: 对应java类用@ConfigurationProperties注解来配置
IDEA提示:
需要在pom文件中导入配置依赖:
<!-- 配置依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
① 定义一个Person类,用来拿配置文件里配置的值
package com.example.demo.bean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
* @ConfigurationProperties:表示该类的所有属性均从配置文件中获取
* prifix要对应配置文件中的词头
* @Component: 只有将组件加到容器中,才能使用容器提供的功能
* @ConfigurationProperties(prefix = "person") 默认从全局配置文件中拿值
*/
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private String country;
private int age;
private Map<String,Object> map;
private List<Integer> list;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
public List<Integer> getList() {
return list;
}
public void setList(List<Integer> list) {
this.list = list;
}
/**
* 重写toString 方便输出查看
* @return
*/
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", country='" + country + '\'' +
", age=" + age +
", map=" + map +
", list=" + list +
'}';
}
}
② 在yml文件中定义参数
person:
name: Tom
country: America
age: 20
map: {p1: eat, p2: music}
list:
- 1400
- 1900
③ 在测试类中注入person类,并输出
package com.example.demo;
import com.example.demo.bean.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class DemoApplicationTests {
@Autowired
private Person person;
@Test
void contextLoads() {
System.out.println(person);
}
}
④ 输出结果
4. properties实例1
同样上述例子,将yml内的配置配置到properties文件中,如下:
person.name=Alice
person.age=14
person.country=Canada
person.map.p1=playing...
person.map.p2=travel
person.list=13,245,4666
输出结果:
如果配置内容出现中文乱码,配置IDEA:
File → settings → File Encodings
Transparent native-to-ascii conversion 自动转换ASCII编码
5. yml实例2: 对应java类用@Value注解来配置
package com.example.demo.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
* @ConfigurationProperties:表示该类的所有属性均从配置文件中获取
* @Component: 只有将组件加到容器中,才能使用容器提供的功能
* @Value: 一一指定值,支持spEl
*/
@Component
public class Person {
@Value("${person.name}")
private String name;
@Value("${person.country}")
private String country;
@Value("#{14*2-5}")
private int age;
private Map<String,Object> map;
private List<Integer> list;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
public List<Integer> getList() {
return list;
}
public void setList(List<Integer> list) {
this.list = list;
}
/**
* 重写toString 方便输出查看
* @return
*/
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", country='" + country + '\'' +
", age=" + age +
", map=" + map +
", list=" + list +
'}';
}
}
yml文件同yml实例1,输出结果:
6. 其他注解:@PropertySource和@ImportResource
@propertySource:加载指定的配置文件
@PropertySource(value = {"classpath:person.properties"})
@ConfigurationProperties(prefix = "person")
@Componet
public class Person {
...
}
@ImportResource: 标注在一个配置类上,可以导入Spring的配置文件,让文件内容生效
@ImportResource(locations = {"classpath:beans.xml"})
7. springboot给容器中添加组件
/**
* @Configuration: 配置类注解,替代之前的Spring配置文件
*
*/
@Configuration
public class MyConfig {
// 将方法的返回值添加到容器中, 容器中组件的id默认为方法名
@Bean
public HelloService helloService(){
return new HelloService();
}
}
8. 配置文件占位符
① 随机数
$ {random.value}、$ {random.int} 、$ {random.long}、$ {random.int(10)}
$ {random.int[1024,65536]}
person:
age: ${random.int(10)}
② 指定默认值
person:
name: Tom
#如果没有找到person.age值,默认为15
description: ${person.age:15}_${person.name}
9. Profile:Spring对不同环境的配置功能
主配置文件编写时的文件名:application-{profile}.properties/yml,默认使用的是application.properties/yml。
① yml指定:
server:
port: 8081
spring:
profiles:
active: prod
---
server:
port: 8083
spring:
profiles: dev
---
server:
port: 8084
spring:
profiles: prod #指定属于哪个环境
② peroperties指定:
spring.profiles.active=dev
③ 命令行指定:
–spring.profiles.active=dev
④ 虚拟机参数:
-Dspring.profiles.active=dev
10. 配置文件的加载位置
springboot启动时扫描配置文件的位置:(按优先级大小排列)
file: ./config/ 项目根目录下的config文件夹
file: ./ 项目根目录
classpath: /config/ 类文件夹下的config文件夹
classpath: / 类文件夹下
如果配置文件直接的配置冲突,高优先级将会覆盖低优先级的配置。