一、SpringBoot基础
What: SpringBoot的设计是为了尽可能快的跑起来Spring应用程序,并尽量减少配置文件。
1.1 约定优于配置
What: 系统、类库或框架应该假定合理的默认值,而不是要求开发人员提供不必要的配置。
举例:
-
如Maven中约定 源码目录为
src/main/java/
测试目录为src/test/java/
打包方式为jar
包输出目录为target/
-
如Spring Boot 中Tomcat默认的hostname是localhost,默认的端口是8080。
-
如说模型中有一个名为User的类,那么数据库中对应的表就会默认命名为user。只有在偏离这一个约定的时候,例如想要将该表命名为system_user,才需要写有关这个名字的配置。
1.2 SpringBoot
1.2.1 Spring的优缺点分析
优点:
IOC解耦,AOP动态增强等
缺点:
- Spring XML配置文件是重量级的。
- 项目的依赖管理复杂。搭建环境依赖的库与坐标很多。
1.2.2 SpringBoot 解决Spring的问题
SpringBoot基于约定优于配置的思想进行解决上述两个缺点。依靠起步依赖和自动配置进行解决。
- 起步依赖:
把某种功能依赖的坐标打包到一起,提供一些默认的功能,如 xxxxstarter
-
自动配置:
springboot自动将一些配置类的bean注册进ioc容器,在需要使用的地方用@autowired或@resource注解进行引用。
1.3 SpringBoot Demo项目创建
1.3.1 使用Spring Initializr方式构建Spring Boot项目
Intellij idea中新建项目
使用Spring Initializr 创建springboot项目(需要联网)
填写项目相关信息
选择springboot版本和选择依赖包。(这里需要说明,jdk版本1.8建议选择3.0.0一下的版本,高版本的springboot包可能使用更高版本的jdk编译,如:3.0.4用的是jdk17)
完成创建
创建完成的项目目录结构如下图:
- main
- java
- Springboot01DemoApplication类 项目主程序启动类,该类建议放在包的根部,如
cn.shutdown
因为启动会扫描该类所在目录及下级目录的文件
- Springboot01DemoApplication类 项目主程序启动类,该类建议放在包的根部,如
- resources
- static 静态资源目录
- templates 模板文件目录
- application.properties 全局配置文件
- java
- test
- java
- Springboot01DemoApplicationTests 项目测试类
- java
1.3.2 创建测试controller及测试类
测试controller代码
package cn.shutdown.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author domino
*/
@RestController //相当于配置了@ResponseBody+ @Controller
public class HelloController {
@RequestMapping("/demo")
public String demo() {
return "hello,springboot";
}
}
启动web项目,访问测试地址
1.3.3 单元测试和热部署
pom文件引入测试依赖启动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
添加测试类
注解说明:
@RunWith
: 测试启动器,并加载spring boot测试注解@SpringBootTest
: 标记该类为springboot单元测试类,并加载项目的applicationContext上下文环境
package cn.shutdown;
import cn.shutdown.controller.HelloController;
import org.junit.Assert;
import org.junit.jupiter.api.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) //测试启动器,并加载spring boot测试注解
@SpringBootTest //标记该类为springboot单元测试类,并加载项目的applicationContext上下文环境
class Springboot01DemoApplicationTests {
@Autowired
private HelloController helloController;
@Test
void contextLoads() {
String demo = helloController.demo();
System.out.println(demo);
Assert.assertEquals(demo, "hello,springboot");
}
}
测试运行结果
1.3.3 热部署配置
1)添加 spring-boot-devtools热部署依赖启动器
<!-- 引入热部署依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
2)Intellij idea 热部署配置
-
Compiler 配置
-
Registry配置
打开Registry 配置面板 ,快捷键
ctrl + shift + alt + /
Mac 快捷键为command+ shift + option + /
将
compiler.automake.allow.when.app.running
选项进行勾选
1.4 全局配置文件
全局配置文件可以对一些默认配置值进行修改,如server.port=8081
,也可以用来定义自定义的属性。可以用application.properties或application.yml作为全局配置文件。一般放在src/main/resource
目录下。Spring Initializr会默认在src/main/resource
下创建一个空的application.properties配置文件。
1.4.1 自定义配置测试
依赖: 自定义的属性springboot无法自动识别,所以引入如下依赖,以便编写配置时出现代码提示的效果。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
配置类
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
* @author domino
*/
@Data
@Component //将Person类作为bean注入到spring容器当中
@ConfigurationProperties(prefix = "person") //将配置文件中以person为前缀的属性注入到该类中
public class Person {
private int id;
private String name;
private List hobby;
private String[] family;
private Map map;
private Pet pet;
}
@Component
注解作用是将Person类对象作为bean注入到spring容器当中。只有这样才能被@ConfigurationProperties
注解进行赋值。@ConfigurationProperties(prefix = "person")
注解的作用是将配置文件中以person
为前缀的属性注入到该类中。
import lombok.Data;
/**
* 注入配置类的对象类
* @author domino
*/
@Data
public class Pet {
private String type;
private String name;
}
application.yml中定义自定义配置,如果同时存在application.yml和application.properties配置文件,application.properties配置文件会覆盖application.yaml配置文件。application.properties遇到中文会有乱码问题,推荐使用application.yml。yaml有行内式写法和行外式写法,行内式写法比较简洁。
person:
# 数组类型属性
family: [父亲,母亲]
# 集合类型属性
hobby: [看书,运动]
# 整型属性
id: 1
# map类型属性
map: {k1: v1, k2: v2}
# 字符串类型属性
name: domino
# 对象类型属性
pet: {type: cat, name: 咪咪}
自动注入自定义实体中
package cn.shutdown.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
* @author domino
*/
@Data
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private int id;
private String name;
private List hobby;
private String[] family;
private Map map;
private Pet pet;
}
测试代码如下
package cn.shutdown;
import cn.shutdown.config.Person;
import cn.shutdown.controller.HelloController;
import com.alibaba.fastjson.JSONObject;
import org.junit.Assert;
import org.junit.jupiter.api.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) //测试启动器,并加载spring boot测试注解
@SpringBootTest //标记该类为springboot单元测试类,并加载项目的applicationContext上下文环境
class Springboot02DemoApplicationTests {
@Autowired
private HelloController helloController;
@Autowired
private Person person;
@Test
void contextLoads() {
String demo = helloController.demo();
System.out.println(demo);
System.out.println(JSONObject.toJSONString(person));
}
}
从运行结果可以看到,正确输出了Person对象的全部属性。配置文件属性通过相关注解完成属性注入。
hello,springboot domino
{"family":["父亲","母亲"],"hobby":["看书","运动"],"id":1,"map":{"k1":"v1","k2":"v2"},"name":"domino","pet":{"name":"咪咪","type":"cat"}}
要注意的是,使用@ConfigurationProperties
注解要求实体类有set方法,如果没有,可以使用@Value
注解分别对每个属性进行注入设置。可以免去属性的setXX()方法。而@Value
注解只只能对普通类型属性进行赋值,不支持Map、对象、数组、List等类型,如果赋值会报错。
1.5 自定义配置文件
自定义配置文件无法直接被Springboot识别,需要手动加载。
1.5.1 使用@PropertySource
加载自定义配置文件
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
* @author domino
*/
@Data
@Component
@PropertySource("classpath:test.properties") //加载指定配置文件
@ConfigurationProperties(prefix = "test") //按前缀注入属性
public class MyProperties {
private int id;
private String name;
}
配置文件 test.properties
test.id=110
test.name=test
测试代码
@RunWith(SpringRunner.class)
@SpringBootTest
class Springboot02DemoApplicationTests {
@Autowired
private MyProperties myProperties;
@Test
public void testMyProperties() {
System.out.println(JSONObject.toJSONString(myProperties));
}
}
输出结果
{"id":110,"name":"test"}
1.6 使用@Configuration
自定义配置类
SpringBoot推荐使用配置类的方式向Spring容器中添加和配置组件,通常用@Configration
注解定义一个配置类,SpringBoot会自动扫描和识别配置类,从而替换传统的Spring框架中的XML配置文件。
定义一个配置类后,使用@Bean注解进行组件配置,将方法返回的对象注入到Spring容器中,并且组件名称默认使用的是方法名,也可以使用@Bean
注解的 name
或value属性自定义组件的名称。
自定义类:
/**
* @author domino
*/
public class MyService {}
自定义配置类:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author domino
*/
@Configuration
public class MyConfig {
@Bean
public MyService myService01() {
return new MyService();
}
}
测试方法:
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
class Springboot02DemoApplicationTests {
@Autowired
private ApplicationContext applicationContext;
@Test
public void testMyConfig() {
System.out.println(applicationContext.containsBean("myService01"));
}
}
运行结果为true,说明配置类成功扫描了myService01()
方法返回的MyService
对象作为组件注册到到Spring容器当中,并且该组件的id默认名称为方法名myService01
。使用自定义配置类的形式完成了向Spring容器进行组 件的添加和配置。
true
1.7 参数间引用
SpringBoot配置文件中,配置文件的属性值可以进行参数间引用。即后配置的属性可以引用之前已经配置过值的属性。
参数间引用使用 ${xx}
格式进行引用。如:
app.name=MyApplication
app.description=this application's name is ${app.name}