推荐课程:03.快速入门-示例Demo_哔哩哔哩_bilibili
官方笔记:SpringBoot3全栈指南 (yuque.com)
目录
01 -- 示例demo
1. 在新建项目创建一个Maven 模块
2. 引入 spring-boot-starter-parent 和 spring-boot-starter-web 依赖
3. 指示 Spring Boot 启动类
4. 构建控制器
5. 启动
6. 使用Maven打包
02 -- 特性小结
1. 简化整合
2. 简化开发
3. 简化配置
4. 简化部署
5. 简化运维
03 -- spring initializer
04 -- 应用分析
1. 依赖管理机制
2. 自动配置机制
05 -- 核心技能
1. 常用注解
2. 组件注册 ✫✫✫✫
3. 条件注解 ✫✫✫✫
4. 属性绑定 ✫✫✫✫
01 -- 示例demo
1. 在新建项目创建一个Maven 模块
2. 引入 spring-boot-starter-parent 和 spring-boot-starter-web 依赖
spring-boot-starter-parent
是 Spring Boot 提供的一个用于构建 Spring Boot 项目的父项目(Parent Project)。通过使用spring-boot-starter-parent
作为项目的父项目,你可以继承 Spring Boot 默认的依赖管理、插件配置和默认配置等(这是必要的,如果缺省Maven 将会默认使用),从而简化项目的配置和构建过程。
spring-boot-starter-web
是 Spring Boot 提供的一个用于构建 Web 应用程序的起步依赖(Starter Dependency)。通过引入spring-boot-starter-web
,你可以快速地构建基于 Spring MVC 的 Web 应用程序,无需手动管理依赖和配置。
<!-- 所有springboot项目都必须继承自 spring-boot-starter-parent --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.0.5</version></parent><dependencies><!-- web开发的场景启动器 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
3. 指示 Spring Boot 启动类
package org.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class MainApplication {public static void main(String[] args) {SpringApplication.run(MainApplication.class,args);}
}
4. 构建控制器
package org.example.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;//@ResponseBody // 标记返回纯文本
//@Controller // 标识一个类作为控制器,用于处理 HTTP 请求并返回相应的视图或数据@RestController // 以上两个注解的合成注解
public class HelloController {@GetMapping("/hello")public String hello(){return "Hello,Spring Boot 3!";}
}
5. 启动
6. 使用Maven打包
<!-- SpringBoot应用打包插件--><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
查看打包结果:
打包成jar包后,可以直接在CMD中直接使用Java -jar运行。
D:\JavaCode\app-demo>Java -jar boot3-01-demo-1.0-SNAPSHOT.jar
02 -- 特性小结
1. 简化整合
导入相关的场景,拥有相关的功能。场景启动器
默认支持的所有场景:Developing with Spring Boot
- 官方提供的场景:命名为:
spring-boot-starter-*
- 第三方提供场景:命名为:
*-spring-boot-starter
场景一导入,万物皆就绪
- 开发什么场景,导入什么场景启动器。
- 导入“场景启动器”。 场景启动器 自动把这个场景的所有核心依赖全部导入进来。
2. 简化开发
无需编写任何配置,直接开发业务
3. 简化配置
application.properties
:
- 集中式管理配置。只需要修改这个文件就行 。
- 配置基本都有默认值
- 能写的所有配置都在: Common Application Properties
4. 简化部署
打包为可执行的jar包。
linux服务器上有java环境。
5. 简化运维
修改配置(外部放一个application.properties文件)、监控、健康检查。
03 -- spring initializer
一键创建好整个项目结构
04 -- 应用分析
1. 依赖管理机制
自定义版本号
- 利用maven的就近原则
-
- 直接在当前项目
properties
标签中声明父项目用的版本属性的key,遵循就近原则。 - 直接在导入依赖的时候声明版本
- 直接在当前项目
2. 自动配置机制
- 自动配置的 Tomcat、SpringMVC 等
-
- 导入场景,容器中就会自动配置好这个场景的核心组件。
- 以前:DispatcherServlet、ViewResolver、CharacterEncodingFilter....
- 现在:自动配置好的这些组件
- 验证:容器中有了什么组件,就具有什么功能
- 默认的包扫描规则(默认从主程序开始,controller只会从属主程序执行)
-
@SpringBootApplication
标注的类就是主程序类- SpringBoot只会扫描主程序所在的包及其下面的子包,自动的component-scan功能
- 自定义扫描路径(改变执行顺序)
-
-
- @SpringBootApplication(scanBasePackages = "com.atguigu")
@ComponentScan("com.atguigu")
直接指定扫描的路径
-
非正确主从位置:
执行结果:
自定义扫描路径:
package org.example.boot;import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;//@SpringBootApplication(scanBasePackages = "org.example")
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("org.example")
public class Boot302DemoApplication {public static void main(String[] args) {//java10: 局部变量类型的自动判断var ioc = SpringApplication.run(Boot302DemoApplication.class, args);//1、获取容器中所有组件的名字String[] names = ioc.getBeanDefinitionNames();//2、挨个遍历:// dispatcherServlet、beanNameViewResolver、characterEncodingFilter、multipartResolver// SpringBoot把以前配置的核心组件现在都给我们自动配置好了。for (String name : names){System.out.println(name);}}}
@SpringBootApplication(scanBasePackages = "org.example")
等于以下三个注解:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("org.example")
自定义扫描路径后:
- 配置默认值 ✫✫✫✫
-
- 配置文件的所有配置项是和某个类的对象值进行一一绑定的。
- 绑定了配置文件中每一项值的类: 属性类。
- 比如:
-
-
ServerProperties
绑定了所有Tomcat服务器有关的配置MultipartProperties
绑定了所有文件上传相关的配置- ....参照官方文档:或者参照 绑定的 属性类。
-
配置文件的所有配置项是和某个类的对象值进行一一绑定的:
- 按需加载自动配置 ✫✫✫✫
-
- 导入场景
spring-boot-starter-web
- 场景启动器除了会导入相关功能依赖,导入一个
spring-boot-starter
,是所有starter
的starter
,基础核心starter spring-boot-starter
导入了一个包spring-boot-autoconfigure
。包里面都是各种场景的AutoConfiguration
自动配置类- 虽然全场景的自动配置都在
spring-boot-autoconfigure
这个包,但是不是全都开启的。
- 导入场景
-
-
- 导入哪个场景就开启哪个自动配置
-
05 -- 核心技能
1. 常用注解
SpringBoot摒弃XML配置方式,改为全注解驱动
2. 组件注册 ✫✫✫✫
@Configuration、@SpringBootConfiguration
@Bean、@Scope
@Controller、 @Service、@Repository、@Component
@Import
@ComponentScan
- @Configuration,@Bean,@Scope注解
@Configuration:这是一个配置类,@Configuration 注解表示该类是一个配置类,其中包含用于配置 bean 的方法。
@Bean:申明这是一个bean类,告诉 Spring 容器要将某个实体类的实例作为一个 bean 注册到容器中。
@Scope :用于指定 Spring bean 的作用域。
- prototype:每次请求该 bean 时都会创建一个新的实例。每个实例都是独立的,没有共享状态。
package org.example.boot.bean;public class User {private Long id;private String name;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
package org.example.boot.bean;public class Cat {private Long id;private String name;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
package org.example.boot.config;import org.example.boot.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration // 这是一个配置类,@Configuration 注解表示该类是一个配置类,其中包含用于配置 bean 的方法。
public class AppConfig {@Bean("hahabean") // Bean注解,申明这是一个bean类,告诉 Spring 容器要将某个实体类的实例作为一个 bean 注册到容器中public User user(){var user = new User();user.setId(1L);user.setName("zhangsan");return user;}
}
主程序:
package org.example.boot;import org.example.boot.bean.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;@SpringBootApplication
public class Boot302DemoApplication {public static void main(String[] args) {var ioc = SpringApplication.run(Boot302DemoApplication.class, args);String[] names = ioc.getBeanNamesForType(User.class);for (String name : names){System.out.println(name);}Object bean1 = ioc.getBean("hahabean");Object bean2 = ioc.getBean("hahabean");System.out.println(bean1 == bean2);}}
执行结果:
- @Import:导入第三方组件。
@Import:向Spring容器中导入一个组件,默认组件名为全类名。
package org.example.boot.config;import org.example.boot.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Scope;@Import(CatConfig.class) // 向容器中导入一个组件,默认组件名为全类名
@Configuration // 这是一个配置类,@Configuration 注解表示该类是一个配置类,其中包含用于配置 bean 的方法。
public class AppConfig {@Scope("prototype")@Bean("hahabean") // Bean注解,申明这是一个bean类,告诉 Spring 容器要将某个实体类的实例作为一个 bean 注册到容器中public User user(){var user = new User();user.setId(1L);user.setName("zhangsan");return user;}
}
3. 条件注解 ✫✫✫✫
如果注解指定的条件成立,则触发指定行为
@ConditionalOnXxx
@ConditionalOnClass:如果类路径中存在这个类,则触发指定行为
@ConditionalOnMissingClass:如果类路径中不存在这个类,则触发指定行为
@ConditionalOnBean:如果容器中存在这个Bean(组件),则触发指定行为
@ConditionalOnMissingBean:如果容器中不存在这个Bean(组件),则触发指定行为
场景:
- 如果存在
CatConfig
这个 类,给容器中放一个Cat
组件,名cat01, - 否则,就给容器中放一个
Dog
组件,名dog01 - 如果系统中有
dog01
这个 组件,就给容器中放一个 User组件,名zhangsan - 否则,就放一个User,名叫lisi
@ConditionalOnBean(value=组件类型,name=组件名字):判断容器中是否有这个类型的组件,并且名字是指定的值
主程序:
package org.example.boot;import org.example.boot.bean.Cat;
import org.example.boot.bean.Dog;
import org.example.boot.bean.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Boot302DemoApplication {public static void main(String[] args) {//java10: 局部变量类型的自动判断var ioc = SpringApplication.run(Boot302DemoApplication.class, args);for (String s : ioc.getBeanNamesForType(Cat.class)){System.out.println("cat:" + s);}for (String s : ioc.getBeanNamesForType(Dog.class)){System.out.println("Dog:" + s);}for (String s : ioc.getBeanNamesForType(User.class)){System.out.println("User:" + s);}}}
Dog.py:
package org.example.boot.bean;public class Dog {private Long id;private String name;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
AppConfig2.py:
package org.example.boot.config;import org.example.boot.bean.Cat;
import org.example.boot.bean.Dog;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig2 {@ConditionalOnClass(name="org.example.boot.config.CatConfig") // 如果类路径中存在这个类,则触发指定行为@Beanpublic Cat cat01(){return new Cat();}@ConditionalOnMissingClass(value="org.example.boot.config.CatConfig") // 如果类路径中不存在这个类,则触发指定行为@Beanpublic Dog Dog01(){return new Dog();}}
CatConfig.py:
package org.example.boot.config;import org.example.boot.bean.Cat;public class CatConfig {public Cat cat(){var cat = new Cat();cat.setId(1L);cat.setName("zhangsan");return cat;}
}
执行结果:
去掉 CatConfig 并注释掉AppConfig里的@import(CatConfig.class)注解,执行结果:
4. 属性绑定 ✫✫✫✫
@Component:添加"@Component"注解,可以告诉Spring框架将该类实例化为一个Bean,并由Spring容器进行管理。
@ConfigurationProperties: 声明组件的属性和配置文件哪些前缀开始项进行绑定。
@EnableConfigurationProperties:快速注册注解。
- 场景:SpringBoot默认只扫描自己主程序所在的包。如果导入第三方包,即使组件上标注了 @Component、@ConfigurationProperties 注解,也没用。因为组件都扫描不进来,此时使用@EnableConfigurationProperties就可以快速进行属性绑定并把组件注册进容器。
将容器中任意组件(Bean)的属性值和配置文件(application.properties)的配置项的值进行绑定
- 1、给容器中注册组件(@Component、@Bean),@Component一般用于bean类,@Bean一般用于config类。
- 2、使用 @ConfigurationProperties 声明组件和配置文件(application.properties)的哪些配置项进行绑定
pig.py:
package org.example.boot.bean;import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;//@Component
public class Pig {private Long id;private String name;private Integer age;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() { //重写 toString() 方法,返回了包含对象的 name 和 age 属性的字符串表示形式。return "Pig{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}
}
去掉@Component也可以实现相同的功能,在AppConfig.py配置类里加入:
@Beanpublic Pig pig(){return new Pig();}
两种方法的目的都是为了将pig组件加入 spring 容器。
在主方法里加入:
Pig pig = ioc.getBean(Pig.class);System.out.println("pig:" + pig);
执行结果:
sheep.py:
package org.example.boot.bean;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@ConfigurationProperties(prefix = "sheep")
public class sheep {private Long id;private String name;private int age;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "sheep{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}
}
在AppConfig.py主类上加上@EnableConfigurationProperties(value = sheep.class)
在主方法里加入:
sheep sheep = ioc.getBean(sheep.class);System.out.println("sheep:" + sheep);
执行结果:
06 -- YAML配置文件
- 使用
.yaml
或.yml
作为文件后缀基本语法:
- 大小写敏感
- 使用缩进表示层级关系,k: v,使用空格分割k,v
- 缩进时不允许使用Tab键,只允许使用空格。换行
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
- # 表示注释,从这个字符一直到行尾,都会被解析器忽略。
支持的写法:
- 对象:键值对的集合,如:映射(map)/ 哈希(hash) / 字典(dictionary)
- 数组:一组按次序排列的值,如:序列(sequence) / 列表(list)
- 纯量:单个的、不可再分的值,如:字符串、数字、bool、日期
xml:
server.port = 9999 sheep.id = 2 sheep.name = 肖恩 sheep.age = 7yml:
server:port: 9999sheep:id: 2name: 肖恩age: 7
07 -- 日志
如同JDBC和mysql,日志门面组件和日志实现组件是一一对应的。
1. 简介
- Spring使用commons-logging作为内部日志,但底层日志实现是开放的。可对接其他日志框架。
- spring5及以后 commons-logging 被spring直接自己写了。
- 支持 jul,log4j2,logback。SpringBoot 提供了默认的控制台输出配置,也可以配置输出为文件。
- logback是默认使用的。
- 虽然日志框架很多,但是我们不用担心,使用 SpringBoot 的默认配置就能工作的很好。
SpringBoot怎么把日志默认配置好的:
1、每个
starter
场景,都会导入一个核心场景spring-boot-starter
2、核心场景引入了日志的所用功能
spring-boot-starter-logging
3、默认使用了
logback + slf4j
组合作为默认底层日志4、
日志是系统一启动就要用
,xxxAutoConfiguration
是系统启动好了以后放好的组件,后来用的。5、日志是利用监听器机制配置好的。
ApplicationListener
。6、日志所有的配置都可以通过修改配置文件实现。以
logging
开始的所有配置
2. 日志格式
2023-03-31T13:56:17.511+08:00 INFO 4944 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2023-03-31T13:56:17.511+08:00 INFO 4944 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.7]
默认输出格式:
- 时间和日期:毫秒级精度
- 日志级别:ERROR, WARN, INFO, DEBUG, or TRACE.
- 进程 ID
- ---: 消息分割符
- 线程名: 使用[]包含
- Logger 名: 通常是产生日志的类名
- 消息: 日志记录的内容
注意: logback 没有FATAL级别,对应的是ERROR
日志文件输出:
指定 logging.file.name 和 logging.file.path 同时存在时,会优先 logging.file.name 配置项。
# 指定日志文件路径
# logging.file.path=D://
# 指定日志文件名的同时也可以指定指定路径
logging.file.name=D://demo.log