#SpringBoot#
本文基于 SpringBoot 2.0 最新稳定版 2.7.6 ;目前 SpringBoot 3.0已经发布,后续会体验新版新特性。
官网:Spring Boot
SpringBoot 程序的优点
- 起步依赖(简化依赖配置)
- 自动配置(简化常用工程相关配置)
- 辅助功能(内置服务器,.....)
快速上手 SpringBoot 工程
联网初始化 SpringBoot
SpringBoot 官方初始化链接:https://start.spring.io
Aliyun 初始化链接:http://start.aliyun.com
国内设置 aliyun SpringBoot 初始化链接
配置如下图
选择 SpringBoot 版本 以及 需要引入的依赖 后 点击下一步
整体目录结构如下:
创建一个 Controller 进行测试
//REST模式
@RestController
@RequestMapping("/books")
public class BookController {
@GetMapping
public String getById(){
System.out.println("SpringBoot is running....");
return "SpringBoot is running....";
}
}
启动 SpringBoot
找到 SpringBoot 启动类,DEBUG 模式运行
日志如下图:
访问刚才写的接口 localhost:8080/books
最简单 SpringBoot 工程所包含的基础文件
- pom.xml
- Application 启动类
@SpringBootApplication
public class Springboot01QuickstartApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot01QuickstartApplication.class, args);
}
}
手工初始化 SpringBoot
不需要联网创建,但是 maven 依赖需要联网下载,之前创建过的话,本地仓库有依赖也不需要联网
创建一个空的 Maven 模块
这里是没有启动类的,并且 pom.xml 文件中也很干净
接下来我们需要 在 pom.xml 文件中 使用 parent 标签引入 SpringBoot 的父POM
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
父POM中包含很多依赖,且统一规定了版本,但是只是声明,如果需要使用,需要在下面进行引入才可以使用
引入我们需要的依赖 web 依赖(可以看到,无需填写版本号,也能引入依赖)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
插件目前只是打包时使用,我们暂且不用引入。
组合好的 pom.xml 文件如图:
刷新 Maven 后,创建一个新的 SpringBoot 启动类
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
同样,创建一个 controller ,启动后测试一下
@RestController
@RequestMapping("/books")
public class BookController {
@GetMapping
public String helloSpingBoot(){
String result = "Hello,SpringBoot!";
System.out.println(result);
return result;
}
}
SpringBoot pom.xml 解析
spring-boot-starter-parent 规范依赖版本
- 开发 SpringBoot 工程要继承 spring-boot-starter-parent
- spring-boot-starter-parent 中定义了非常多个依赖管理
- 继承 parent 模块可以有效规避多个依赖使用相同技术时出现的依赖冲突
- spring-boot-starter-parent 仅仅是定义了依赖和版本,并未真正引入依赖,我们可以在 子pom 中按需引入,且不用显式的声明版本(如果pom爆红,也可以手动指定版本)
在所有的 SpringBoot 工程中的 pom.xml 中 都引入了 spring-boot-starter-parent 父POM
点击进入 父pom 文件,发现还有一个 spring-boot-dependencies 的 父pom 文件,这里就是管理依赖与指定版本的pom文件
spring-boot-dependencies pom 概览
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.6</version>
<packaging>pom</packaging>
<name>spring-boot-dependencies</name>
<description>Spring Boot Dependencies</description>
<properties>
<activemq.version>5.16.5</activemq.version>
...省略更多版本信息
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-amqp</artifactId>
<version>${activemq.version}</version>
</dependency>
...省略更多依赖信息
<dependencies>
</dependencyManagement>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>${build-helper-maven-plugin.version}</version>
</plugin>
</plugins>
...省略更多插件信息
</pluginManagement>
</project>
可以看到这里使用 properties 定义了很多依赖和插件的版本信息,然后使用 dependencyManagement 和
pluginManagement 标签 用来管理依赖和插件的版本,子项目引入后无需声明版本号。
Maven 中的dependencyManagement元素提供了一种管理依赖版本号的方式。在dependencyManagement元素中声明所依赖的jar包的版本号等信息,那么所有子项目再次引入此依赖jar包时则无需显式的列出版本号。Maven会沿着父子层级向上寻找拥有dependencyManagement 元素的项目,然后使用它指定的版本号。
spring-boot-starter 快速配置依赖
- 通过依赖传递的性质,只需引入一个功能的 spring-boot-start,就能自动引入功能所需要的所有依赖。
- 通过 spring-boot-start ,可以减少依赖配置,快速配置。
以 spring-boot-starter-web 为例
点击进入发现是一个pom文件
查看依赖元素,是在这里引入了 springmvc 以及 web 依赖
在 spring-boot-starter-web 中还引入了另一个starter -> spring-boot-starter-tomcat,点击进入,同样是一个pom ,查看依赖,原来是在这里引入了 tomcat 的相关依赖。
SpringBoot 启动引导类
- SpringBoot 的引导类是工程的执行入口,运行 main 方法就可以启动项目
- SpringBoot 工程运行后会初始化 Spring 容器,扫描引导类所在包下的所有组件,加载为bean
- 自动配置非常牛掰!!!!
SpringBoot启动类 获取 Spring 容器
SpringApplication.run() 方法可以返回 spring 容器对象,通过容器对象可以获取 bean
@SpringBootApplication
public class Application {
public static void main(String[] args) {
// 获取到 Spring 容器
ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);
// 通过容器获取 bean
BookController bean = ctx.getBean(BookController.class);
System.out.println("bean======>" + bean);
}
}
@SpringBootApplication 注解
@SpringBootApplication 是一个复合注解
@SpringBootConfiguration 配置类
其实就是一个配置类
@EnableAutoConfiguration 自动配置
这个非常重要,原理解析后面会详细介绍
@ComponentScan 组件包扫描
默认配置扫描 SpringBoot 启动当前包下的所有组件
内嵌 Tomcat web容器
- SpringBoot 默认支持三款 web服务器:Tomcat、Jetty、Undertow;默认使用 Tomcat。
- 内嵌 Tomcat web容器的工作原理是将 Tomcat 服务器作为对象运行,并将该对象交给 Spring 容器管理
- 内嵌 Tomcat web容器是 SpringBoot 辅助功能之一
在查看 spring-boot-starter-web pom依赖时,我们就发现了 spring-boot-starter-tomcat 里面引入了 Tomcat 容器相关的依赖。
更换其他 web 服务器
Jetty 比 Tomcat 更加轻量级,可扩展性更强(相较于 Tomcat),谷歌应用引擎(GAE)已经全面切换为 Jetty
启动后日志:
之前 Tomcat 的日志:
SpringBoot 配置文件
配置文件优先级
properties > yml > yaml
三种配置文件共存,会共存、叠加,相同的配置,优先级高的会覆盖掉优先级低的,不相同的配置则会共同存在。保留下来
properties 配置文件
键值对形式
yml 配置文件
后缀名:yaml / yml 均可,推荐使用 yml,yml 优先级 > yaml
详细介绍参考:yaml 配置文件
官方配置查询文档
找到你对应版本的 SpringBoot ,点击阅读文档
找到 application properties 即可
所有配置都在这里:
yaml 配置绑定
单一配置绑定 @Value("${}")
注意:yaml的值为基本类型(数字、字符串)及其包装类,可以直接解析转换,绑定特殊类型(List、Map、日期等),需要额外处理。
@RestController
@RequestMapping("/books")
public class BookController {
@Value("${chart}")
private String chart;
@Value("${chart2.str}")
private String str;
@Value("${list1[0]}")
private Integer item;
@Value("#{'${list2}'.split(',')}")
private List<Integer> list;
@Value("#{${map2}}")
private Map<String,String> map;
@Value("${datetime}")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime dateTime;
@GetMapping
public String helloSpingBoot(){
String result = "Hello,SpringBoot! Current DateTime:"+dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(result);// Hello,SpringBoot! Current DateTime:2023-02-07 20:04:30
System.out.println(dateTime);// 2023-02-07T20:04:30
System.out.println(chart);// 普通字符串
System.out.println(str);// 层级展示
System.out.println(item);// 1
System.out.println(list);// [1, 2, 3, 4, 5]
System.out.println(map);// {name=zhangsan, sex=male}
return result;
}
}
如果一定要使用 @Value 注解读取,List、Map 在 yaml 中需要使用行内写法,然后在注解内使用 SpEL表达式;
list2: 1,2,3,4,5
map2: '{"name": "zhangsan", "sex": "male"}'
@Value("#{'${list2}'.split(',')}")
private List<Integer> list;
@Value("#{${map1}}")
private Map<String,String> map;
或者使用注解 @ConfigurationProperties
注解,定义一个配置类 Bean
,定义属性用来接收特殊类型,下面会介绍
SpringBoot 环境变量 Environment
使用 @Autowired
注解 自动注入 Environment
,通过getProperty()
方法获取配置文件中的值。
注意: 行外写法获取的值均为 null
# 列表 行外写法
list1:
- 1
- 2
- 3
- 4
- 5
# Map 或 对象 行外写法
map1:
name: "zhangsan"
sex: "male"
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private Environment environment;
@GetMapping("/env")
public String environment(){
String result = environment.getProperty("datetime");
System.out.println(environment.getProperty("list1"));// null 行外写法获取为null
System.out.println(environment.getProperty("list2"));// 1,2,3,4,5
System.out.println(environment.getProperty("map1"));// null 行外写法获取为null
System.out.println(environment.getProperty("map2"));// {"name": "zhangsan", "sex": "male"}
System.out.println(environment.getProperty("chart2.str"));// 层级展示
System.out.println(environment.getProperty("datetime"));// 2023-02-07 20:04:30
return result;
}
}
配置属性类 @ConfigurationProperties
使用 @Component 定义为 Bean
使用 @ConfigurationProperties(prefix = "datesource") 绑定 yaml 配置
注意:prefix 或 value 不能使用驼峰命名
datasource:
driver: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot
username: root
password: root666
@Data
@Component
@ConfigurationProperties(prefix = "datasource")
public class MyDataSource {
private String driver;
private String url;
private String username;
private String password;
}
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private MyDataSource dataSource;
@GetMapping("/config")
public void config(){
System.out.println(dataSource);
// 打印:
//MyDataSource(driver=com.mysql.jdbc.Driver, url=jdbc:mysql://localhost:3306/springboot, username=root, password=root666)
}
}
整合第三方技术
整合 Junit
[[SpringBoot 测试相关]]
新建一个模块,引入 spring-boot-starter
与 spring-boot-starter-test
依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
创建后目录结构,
ApplicationTests 测试类
类上使用 @SpringBootTest 注解,测试方法上使用 @Test 注解
注意:测试类 要与 启动类 包名保持一致,否则会报错,如果不一致,需要再 @SpringBootTest(classes = Application.class) 指定你的启动类
@SpringBootTest
public class ApplicationTests {
/**
* 简单测试一下
*/
@Test
void initTest(){
System.out.println("test=========");
}
}
再定义一个接口与实现类 注册为 bean ,测试 SpringBoot Test 类的依赖自动注入能力
@Repository
public class BookDaoImpl implements BookDao {
@Override
public void save() {
System.out.println("BookDao保存中....");
}
}
将 bean 自动注入进来,运行测试方法。
@SpringBootTest
public class ApplicationTests {
@Autowired
private BookDao bookDao;
@Test
void testBookDao(){
bookDao.save();
}
}
运行结果:
整合 MyBatis
这里只介绍简单使用,详细见 MyBatis
引入基本依赖
<dependencies>
<!-- springboot 基础包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- mysql 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- 测试相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
</dependencies>
数据源配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.33.102:3308/spring_boot?useUnicode=true&characterEncoding=UTF-8&useSSL=true
username: root
password: ferko
# 驼峰映射 createTime : create_time
mybatis:
configuration:
map-underscore-to-camel-case: true
编写 Dao 层,使用 Mapper 注解
/**
* 书籍
*
* @author Ferko
* @date 2023/02/11 07:56
*/@Mapper
public interface BookDao {
/**
* 通过主键获取书籍
*
* @param id 主键
* @return {@link Book }
*/
@Select("select * from te_book where id = #{id}")
public Book getById(Long id);
}
实体类
/**
* 书籍 实体类
*
* @author Ferko
* @date 2023/02/11 07:53
*/@Data
public class Book {
/** 主键 */
private Long id;
/** 类型 */
private String type;
/** 书籍名称 */
private String name;
/** 书籍描述 */
private String description;
/** 价格 */
private String price;
/** 创建时间 */
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
/** 更新时间 */
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
}
使用测试类
@SpringBootTest
public class SpringBootTests {
@Autowired
private BookDao bookDao;
@Test
public void testDao() {
System.out.println(bookDao.getById(1L));
}
}
返回结果
整合 MyBatis-Plus
第三方技术的 starter ,boot-starter 是在后面,mybatis-plus-boot-starter
引入依赖
<dependencies>
<!-- springboot 基础包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- mysql 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- MyBatisPlus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<!-- 测试相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
</dependencies>
配置文件
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.33.102:3308/spring_boot?useUnicode=true&characterEncoding=UTF-8&useSSL=true
username: root
password: ferko
使用之前的 dao 和 entity ,dao 继承 baseMapper<> ,可以获得 MP 定义好的通用方法,无需我们再去写
如果你的表名与实体类名不一致,记得在实体类,加入 @TableName("te_book")
或者是在配置文件 加入全局配置,前提是你所有表名前缀都一致。
/**
* 书籍
*
* @author Ferko
* @date 2023/02/11 07:56
*/
@Mapper
@TableName("te_book")
public interface BookDao extends BaseMapper<Book> {
}
测试类,使用 MP 自带的方法
@SpringBootTest
public class SpringBootTests {
@Autowired
private BookDao bookDao;
@Test
public void test(){
bookDao.selectById(1L);
}
}
运行结果
整合 Druid 连接池
引入依赖
<dependencies>
<!-- springboot 基础包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- mysql 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- druid 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.15</version>
</dependency>
<!-- 测试相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
</dependencies>
配置文件,推荐配置二
# 配置一
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.33.102:3308/spring_boot?useUnicode=true&characterEncoding=UTF-8&useSSL=true
username: root
password: ferko
type: com.alibaba.druid.pool.DruidDataSource
# 配置二 推荐
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.33.102:3308/spring_boot?useUnicode=true&characterEncoding=UTF-8&useSSL=true
username: root
password: ferko
标签:SpringBoot,spring,boot,private,基础知识,public,starter
From: https://www.cnblogs.com/ferko/p/springboot-basic-knowledge-z11vsl1.html