1. SpringBoot概述
1.1 背景
多年来,随着新功能的增加,Spring 变得越来越复杂。若启动一个新的Spring项目,必须添加构建路径或添加 Maven 依赖关系、配置应 用程序服务器、添加 spring 配置。
SpringBoot是解决这个问题的方法。SpringBoot建立在现有spring框架之上。使用 spring 启动,避免 了之前必须做的所有样板代码和配置 。因此, SpringBoot可以帮助我们以很多的工作量, 更加健壮地使用现有的Spring功能。
1.2 SpringBoot特点
独立运行
Spring Boot内嵌了各种servlet容器,Tomcat、Jetty等,不再需要打成war包部署到容器中,Spring Boot只要打成一个可执行的jar包就能独立运行,所有的依赖包都在一个jar包内。
简化配置
spring-boot-starter-web启动器自动依赖其他组件,简少了maven的配置。
自动配置
Spring Boot能根据当前类路径下的类、jar包来自动配置bean,如添加一个spring-boot-starter-web启动器就能拥有web的功能,无需其他配置。
无代码生成和XML配置
Spring Boot配置过程中无代码生成,也无需XML配置文件就能完成所有配置工作,这一切都是借助于条件注解完成的,这也是其核心功能之一。
应用监控
Spring Boot提供一系列端点可以监控服务及应用,做健康检测。
1.3 SpringBoot的优点
减少开发和测试的时间。
使用 JavaConfig 有助于避免使用 XML配置文件的编写。
避免大量的 Maven 导入和各种版本冲突。
通过提供默认值快速开始开发。
没有单独的 Web 服务器需要。这意味着不再需要启动 Tomcat,Glassfish或其他任何东西。
需要更少的配置。因为没有 web.xml 文件。只需添加用@Configuration注解的类,然后添加用@Bean注解的方法,Spring 将自动加载对象并像以前一样对其进行管理。甚至可以将@Autowired 添加到 bean 方法中,使 Spring 自动装入需要的依赖关中。
基于环境的配置使用这些属性,可以将正在使用的环境传递到应用程序:-Dspring.profiles.active = {enviornment}。
在加载主应用程序属性文件后,Spring 将在(application{environment} .properties)中加载后续的应用程序属性文件。
2. SpringBoot项目创建
3. SpringBoot的基础知识点
3.1 application配置文件
3.1.1 配置文件的两种格式
如下图所示,为SpringBoot项目的总配置文件。配置文件分为两种,一种为properities后缀,一种为yaml后缀。
两种格式的配置文件中,properties的优先级更高。接下来将分别介绍两个文件格式的语法。
① properties配置文件
# key=value---注释
server.port=8080
server.servlet.context-path=/aaa
② yaml配置文件
注意:value值需要和冒号留一个空格,这是语法格式。
# 设定端口号、访问路径
server:
port: 8080
servlet:
context-path: /ykx
# 设置属性值
student:
name: ykx
age: 18
sex: man
hobby: running, reading, writing
个人更喜欢yaml配置文件,层级更加清晰。
3.1.2 profile多环境配置
注意,在实际开发中,在不同的阶段,例如开发、测试、生产等,项目使用的配置文件也各不相同。
在SpringBoot项目中,可以为其不同阶段分别创建其适合的配置文件,只需要在总配置文件中激活即可。
除了下图展示的一种激活方式外,还可以使用cmd命令行的方式,使用如下命令:
java –jar xxx1.jar --spring.profiles.active=xxx2 (xxx1表示jar的名称;xxx2表示激活环境)
3.1.3 配置文件常用设置
# 设定端口号、访问路径
server:
port: 8080
servlet:
context-path: /ykx
# 设置实体属性值
student:
name: ykx
age: 18
sex: man
hobby: running, reading, writing
# 激活配置文件
spring:
profiles:
active: test
3.1.4 读取配置文件
我们习惯把一些自己的信息放入配置文件中,便于修改。比如OSS. 支付。 我们还希望通过java代码能够读取到配置文件中自己的信息。springboot提供了两种方式用于读取springboot配置文件中信息的方式。
① @ConfigurationProperties
使用在类上 @ConfigurationProperties(prefix=“前缀”) – 表示读取配置文件中以”前缀“开头的属性值。
实体类
@Component //将对象交给spring创建
@Data
@ConfigurationProperties(prefix = "student")//读取属性文件中student前缀的值
public class Student {
private String name;
private int age;
private String sex;
private List<String> hobby;
}
controller类
@RestController
public class MyController {
//自动注入 创建对象
@Autowired
private Student student;
@GetMapping("/getStudent")
public Student getStudent(){
return student;
}
}
② @Value
该注解只能读取基本类型和字符串类型。
@RestController
public class MyController {
//使用value读取特定属性值
@Value("${student.name}")
private String name;
@GetMapping("/getName")
public String getName(){
return name;
}
}
3.2 注册servlet和filter
3.2.1 注册servlet
① 创建servlet类
创建servlet类,继承HttpServlet类,重写service方法。
package com.ykx.startspringboot.servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("MyServlet被访问了");
}
}
② 创建配置类
使用@Configuration注解,该注解表示该类是配置类,用于替代传统的XML配置方式,定义了Bean的实例化和组装方式。
@Configuration //配置类,用于替代传统的XML配置方式,定义了Bean的实例化和组装方式。
public class ServletConfig {
// 配置servlet
@Bean
public ServletRegistrationBean servletRegistrationBean() {
/**
* 创建一个Servlet注册bean,用于将自定义Servlet注册到Spring Boot的应用程序中。
* 这个bean负责管理Servlet的配置,比如名称、映射路径和启动顺序。
*/
ServletRegistrationBean<Servlet> bean = new ServletRegistrationBean<>();
// 设置Servlet的名称。
bean.setName("myServlet");
// 将MyServlet实例设置为要注册的Servlet。
bean.setServlet(new MyServlet());
// 添加URL映射,指定Servlet处理的请求路径。
bean.addUrlMappings("/my");
// 设置Servlet的加载顺序,数值越小越先加载。
bean.setLoadOnStartup(1);
return bean;
}
}
3.2.2 注册Filter
① 创建filter类
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("过滤器执行了");
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
② 创建配置类
@Configuration
public class FilterConfig {
//配置过滤器
/**
* 配置一个过滤器注册bean,将自定义过滤器MyFilter应用到所有请求中。
*/
@Bean
public FilterRegistrationBean filterRegistrationBean() {
// 创建一个FilterRegistrationBean实例,用于注册和配置过滤器
FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
// 设置过滤器的名称
registrationBean.setName("myFilter");
// 设置过滤器实例
registrationBean.setFilter(new MyFilter());
// 将过滤器应用到所有请求上
registrationBean.addUrlPatterns("/*");
// 返回配置好的过滤器注册bean
return registrationBean;
}
}
3.3 面试题
3.3.1 包扫描原理
Spring Boot的包扫描机制默认通过主应用类上的 @SpringBootApplication注解 读取到其内部的
@ComponentScan
注解,启动类路径扫描器,扫描指定包路径下的类,筛选符合条件的组件类,并解析其注解元数据,生成并注册BeanDefinition
对象到Spring容器中。默认情况下,@ComponentScan
扫描@SpringBootApplication
注解所在类的包及其子包。如果不希望通过默认的扫描,可以在主应用类上自定义@ComponentScan
注解,指定扫描包路径。(注意,路径不可以和默认的重复)Spring Boot自动管理Bean的实例化和依赖注入,大大简化了开发者的配置工作。包扫描机制还支持多种配置选项,如过滤器和自定义扫描器,使其具有很高的灵活性和可扩展性。
① @SpringBootApplication注解
@SpringBootApplication
是一个复合注解,包含了以下三个注解:
@SpringBootConfiguration
: 标识这是一个Spring Boot配置类,实际上是@Configuration
的一个特化版本。@EnableAutoConfiguration
: 启用Spring Boot的自动配置机制。@ComponentScan
: 启用组件扫描,自动发现和注册Spring组件。
② @ComponentScan注解
该注解往往用于主应用类上。
@SpringBootApplication //该注解底层中定义了默认包扫描的路径,即com.ykx.startspringboot
@ComponentScan("com.ykx") //该注解表示扫描指定包下的类,路径不可以和@SpringBootApplication注解默认包扫描路径一致
public class StartSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(StartSpringBootApplication.class, args);
}
}
③ Spring Boot应用启动时的包扫描过程
Spring Boot在启动时进行包扫描的关键步骤如下:
- 启动类路径扫描器:
@ComponentScan
注解被解析,默认情况下,@ComponentScan
扫描@SpringBootApplication
注解所在类的包及其子包,如果没有显式指定basePackages
,则默认扫描主应用类所在包及其子包。解析后会启动ClassPathBeanDefinitionScanner
类路径扫描器。
- 扫描指定包路径:
ClassPathBeanDefinitionScanner
扫描指定的包路径,查找所有符合条件的类文件。
- 筛选组件类:
- 扫描过程中,Spring会根据一系列注解(如
@Component
、@Service
、@Repository
、@Controller
)来筛选组件类。
- 扫描过程中,Spring会根据一系列注解(如
@Component
public class MyComponent {
// ...
}
-
解析注解元数据:
- 扫描到的类会被进一步解析其注解元数据,确定这些类是否需要被注册为Bean。
-
生成Bean定义:
- 对每个符合条件的类,Spring会生成一个
BeanDefinition
对象。这个对象包含了Bean的配置信息,如Bean的类型、作用域、依赖关系等。
- 对每个符合条件的类,Spring会生成一个
注册Bean定义:
BeanDefinition
对象会被注册到Spring的BeanFactory
(通常是DefaultListableBeanFactory
)中。
3.3.2 自动装配原理
Spring Boot的自动装配机制通过结合
spring.factories
文件、然后通过@EnableAutoConfiguration
注解中的@import
注解导入EnableAutoConfigurationImportSelector
来读取所有的自动配置类、以及通过条件注解来控制Bean的注册,自动化了大量常见的配置任务,从而大大简化了应用程序的配置过程。开发者可以通过排除机制和外部化配置来自定义自动装配的行为,同时利用自动配置报告来调试和优化配置。
① spring.factories 文件(重点)
Spring Boot自动装配的核心就是==spring.factories
文件==,该文件位于每个自动配置jar包的==META-INF
目录==中
在该文件种定义了一系列的自动配置类,这些类在项目启动时便被加载。
② @EnableAutoConfiguration注解(重点)
在主应用类上有@SpringBootApplication注解,该注解是一个复合注解,其中包括了@EnableAutoConfiguration注解。
通过@EnableAutoConfiguration
注解中的@Import
注解导入EnableAutoConfigurationImportSelector
,它负责从spring.factories
文件中加载自动配置类。
关于EnableAutoConfigurationImportSelector
- 它会从
spring.factories
文件中读取所有自动配置类的全限定名,并将其作为配置类导入到Spring上下文中。- 它可以通过
spring.autoconfigure.exclude
属性或@EnableAutoConfiguration(exclude = {ClassName.class})
来排除特定的自动配置类。
③ 条件注解(重点)
自动配置类通常使用一系列条件注解来控制Bean的注册:
- @ConditionalOnClass: 当类路径上存在指定的类时,配置才会生效。
- @ConditionalOnMissingBean: 当容器中不存在指定的Bean时,配置才会生效。
- @ConditionalOnProperty: 当配置属性的值满足特定条件时,配置才会生效。
@Configuration
@ConditionalOnClass(DataSource.class)
public class DataSourceAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public DataSource dataSource() {
return new HikariDataSource();
}
}
④ 读取配置属性
- 外部化配置: Spring Boot允许通过外部配置(如application.properties或application.yml)来定制自动配置的行为。
- 属性绑定: 自动配置类可以使用
@ConfigurationProperties
注解将配置属性绑定到Java对象上。
@ConfigurationProperties(prefix = "app.datasource")
public class DataSourceProperties {
private String url;
private String username;
private String password;
// getters and setters
}
⑤ 自动配置类的设计
- 模块化: 自动配置类通常按模块设计,例如
DataSourceAutoConfiguration
、JpaAutoConfiguration
等,每个模块负责特定功能的自动配置。 - 分级加载: 自动配置类可以依赖于其他自动配置类,通过
@AutoConfigureAfter
或@AutoConfigureBefore
注解来控制加载顺序。
⑥ 自动配置报告
启动时,Spring Boot会生成一份自动配置报告,列出哪些自动配置类被应用,哪些被排除,以及原因。这可以通过启用
spring-boot-actuator
模块并访问/actuator/conditions
端点来查看。
# application.properties
logging.level.org.springframework.boot.autoconfigure=DEBUG
⑦ 自动装配注解的源码解析(重点)
3.3.3 Spring Boot 的核心注解
启动类上面的注解是==@SpringBootApplication==,它也是 Spring Boot 的核心注解,主要组合包含了以下3 个注解:
@SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。
@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能——
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。
@ComponentScan:Spring组件扫描。