01、什么是 Spring Boot?核心优势是什么?和传统框架的区别
1. 什么是 Spring Boot?
Spring Boot 是在 Spring 框架基础上推出的一个快速开发框架 。它的核心设计目标是简化 Spring 应用的初始搭建和开发过程 ,通过**"约定大于配置"的理念,"自动装配、起步依赖(starter)"**等机制,让开发者能够以最少的配置,快速创建一个独立的、生产级别的 Spring 应用程序。
2. Spring Boot 的核心优势(6点)
2.1 快速开发(开箱即用)
无需手动配置Spring核心组件(如IOC容器、AOP、MVC),引入对应Starter依赖(如spring-boot-starter-web)后,框架会自动完成核心组件的初始化和配置,极大缩短项目搭建时间
2.2 约定大于配置
框架内置了大量默认约定(如默认端口8080原则,默认配置文件application.properties/yml、默认包扫描规规),开发者只需遵循约定即可,无需编写冗余配置,仅在"约定不满足需求"时做少量自定义配置。
2.3 内置嵌入式容器
内置Tomcat(默认)、Jetty、Undertow等Web容器,无需手动部署到外部容器,项目可直接打包为可执行jar包,通过java -jar命令启动,简化部署和运维。
2.4 起步依赖(Starter)
将常用功能的依赖整合为一个Starter (如 spring-boot-starter-web 整合了Spring MVC、Tomcat,Jackson等Web开发核心依赖),开发者只需引入一个Starter,无需手动管理依赖版本和依赖冲突。
2.5 简化监控与运维
内置Actuator组件,可快速实现应用健康检查、指标监控、日志管理等运维功能,无需额外开发;支持与SpringCloud无缝集成,适配微服务架构。
2.6 无代码生成/无XML配置
完全基于注解驱动,无需生成额外代码,也无需编写XML配置文件,配置方式更简洁、易维
3. Spring Boot 与传统 Spring 框架(如 Spring MVC)的区别
| 特性维度 | 传统 Spring 框架 (如 Spring MVC) | Spring Boot |
|---|---|---|
| 配置方式 | 显式配置 为主。需要编写大量的 XML 配置文件或 Java @Configuration 类来定义 Bean、数据源、事务、MVC 视图解析器等。 |
约定大于配置 。大部分配置通过自动配置完成,开发者只需在 application.properties 中覆盖少数需要定制的属性。 |
| 项目搭建 | 复杂。需要手动选择和添加众多依赖,并解决版本兼容性问题。 | 极其简单。通过 Spring Initializr 网站或 IDE 插件,几秒钟即可生成一个可运行的项目骨架。 |
| 依赖管理 | 开发者需在 pom.xml 或 build.gradle 中手动声明和管理所有依赖及其版本。 |
通过 Starter 依赖进行管理。一个 Starter 包含了一组功能相关的、版本兼容的依赖。 |
| 部署方式 | 需要将应用打包成 WAR 文件,然后部署到外部的 Web 服务器(如独立的 Tomcat)中。 | 打包成可执行 JAR,内嵌了 Web 服务器,可以直接运行。也支持打包成 WAR 部署到外部容器。 |
| 开发体验 | 配置繁琐,启动慢,需要较深的理解才能搭建一个可运行的环境。 | 开箱即用,启动速度快,专注于业务逻辑开发,入门门槛低。 |
| 适用场景 | 适用于对配置有极高定制化需求的大型、复杂遗留系统。 | 适用于快速构建微服务、云原生应用、原型验证和大多数现代企业级应用。 |
4. 总结
简单来说,Spring Boot = Spring 框架 + 自动配置 + 起步依赖 + 内嵌服务器。
02、SpringBoot 的核心注解是什么?各注解的作用分别是什么?
Spring Boot 的核心注解是其"约定大于配置"和"自动装配"理念的具体实现载体。理解这些注解是掌握 Spring Boot 开发的关键。下面将核心注解分为启动类注解 、配置类注解 、Bean 管理注解 、条件装配注解 和其他重要注解五大类进行详细解析。
2.1 启动类注解:@SpringBootApplication
这是 Spring Boot 应用的入口和总开关 ,通常标注在主类(Main Class)上。它是一个组合注解,包含了以下三个核心注解的功能:
-
@SpringBootConfiguration:- 作用 : 表明该类是一个 Spring Boot 的配置类 。它本质上是
@Configuration注解的特化,意味着这个类中可以定义@Bean方法。 - 示例: 主类本身就可以作为配置源。
- 作用 : 表明该类是一个 Spring Boot 的配置类 。它本质上是
-
@EnableAutoConfiguration:- 作用 : 启用 Spring Boot 的自动配置机制 。这是 Spring Boot 的"魔法"之源。添加此注解后,Spring Boot 会根据你引入的 starter 依赖和 classpath 中的类,自动配置 Spring 应用所需的组件。
- 原理 : Spring Boot 在启动时会扫描
META-INF/spring.factories文件(Spring Boot 2.7+ 后为META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports),加载其中声明的自动配置类。这些自动配置类使用@ConditionalOnXxx注解来判断条件是否满足,从而决定是否生效。
-
@ComponentScan:- 作用 : 启用组件扫描 。默认会扫描当前包及其所有子包 ,寻找被
@Component,@Service,@Repository,@Controller等注解标记的类,并将它们注册为 Spring 容器中的 Bean。 - 重要提示 : 如果你的控制器、服务类不在主类所在的包或其子包下,你需要使用
@ComponentScan(basePackages = {"com.your.package"})来指定扫描路径,或者使用@SpringBootApplication(scanBasePackages = "com.your.package")。
- 作用 : 启用组件扫描 。默认会扫描当前包及其所有子包 ,寻找被
代码示例:
java
// 标准的 Spring Boot 应用入口
@SpringBootApplication // 等价于 @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args); // 启动 Spring 应用上下文
}
}
2.2 配置与属性注解
@ConfigurationProperties
-
作用 : 将配置文件(如
application.yml)中的属性批量绑定到一个 Java Bean 上。用于类型安全地读取外部配置,是替代@Value注解的最佳实践,尤其适合处理一组相关的配置项。 -
用法 : 通常与
@Component或@Configuration一起使用,并通过prefix指定配置前缀。 -
示例 :
yaml# application.yml app: user: name: "张三" age: 30 active: truejava@Component @ConfigurationProperties(prefix = "app.user") // 绑定以 `app.user` 开头的所有属性 @Data // Lombok 注解,生成 getter/setter public class UserProperties { private String name; private Integer age; private Boolean active; } // 在 Service 中注入 UserProperties 即可使用
@PropertySource
- 作用 : 指定自定义的配置文件位置 。默认情况下,Spring Boot 只加载
application.properties或application.yml。使用此注解可以加载额外的属性文件。 - 示例 :
@PropertySource("classpath:custom.properties")。注意:它默认不支持 YAML 文件,如需加载 YAML,需要配合YamlPropertySourceFactory类使用。
2.3 Bean 管理相关注解
这些注解继承自 Spring Framework,但在 Spring Boot 中同样至关重要。
@Bean: 在@Configuration类的方法上使用,用于向 Spring 容器注册一个 Bean。Spring Boot 的自动配置类中大量使用此注解来提供默认 Bean。@Autowired: 用于自动注入依赖。在 Spring Boot 中,构造器注入是更推荐的方式(可省略@Autowired)。@Qualifier: 当有多个相同类型的 Bean 时,用于指定要注入的具体 Bean 名称。@Primary: 当有多个相同类型的 Bean 时,被标记为@Primary的 Bean 将作为默认的首选注入对象。
2.4 条件装配注解 (@ConditionalOnXxx)
- @Conditional
条件化创建Bean:只有满足指定条件时,才会注册Bean到容器(SpringBoot大量使用此注解实现自动置)。
衍生注解更常用: @ConditionalOnClass: 当 classpath 下存在指定的类时,配置才生效。例如,自动配置DataSource的前提是存在DataSource.class。@ConditionalOnMissingBean: 当 Spring 容器中不存在 指定类型或名称的 Bean 时,配置才生效。这是实现"配置可覆盖"的关键 。如果你自己定义了一个@Bean,Spring Boot 的默认配置就会因为此条件不满足而跳过。@ConditionalOnProperty: 当指定的配置属性具有特定值(或存在)时,配置才生效。例如,@ConditionalOnProperty(prefix = "spring.datasource", name = "url")。@ConditionalOnWebApplication/@ConditionalOnNotWebApplication: 根据当前应用是否为 Web 应用来决定配置是否生效。@ConditionalOnExpression: 根据 SpEL 表达式的结果来决定。
- 总结:
@ConditionalOnBean:与@ConditionalOnMissingBean相反,当容器中存在指定 Bean 时才生效。@ConditionalOnMissingClass:与@ConditionalOnClass相反,当 classpath 中不存在指定类时才生效。@ConditionalOnResource:当类路径下存在指定的资源文件时才生效。@ConditionalOnJava:根据当前 JVM 版本决定是否生效。
在实际的自动配置类中,这些条件注解经常被组合使用,以实现精细化的装配控制。
java
// 一个典型的自动配置类头部
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class }) // 1. 必须有数据源相关类
@ConditionalOnProperty(prefix = "spring.datasource", name = "url") // 2. 必须配置了数据源 URL
@AutoConfigureAfter({ DataSourceAutoConfiguration.class }) // 3. 在数据源自动配置之后执行
@EnableConfigurationProperties(DataSourceProperties.class) // 4. 启用配置属性绑定
public class MyBatisAutoConfiguration {
// 该配置仅在同时满足条件1和2时才生效
}
2.5 其他重要注解
@SpringBootTest
- 作用 : Spring Boot 的集成测试注解 。用于启动一个完整的、接近于生产环境的 Spring 应用上下文来进行测试。它会自动搜索
@SpringBootConfiguration(通常是你的主类),并加载所有相关的配置。 - 常用属性 :
webEnvironment: 定义测试的 Web 环境类型(如WebEnvironment.MOCK模拟 Servlet 环境,WebEnvironment.RANDOM_PORT在随机端口启动真实服务器)。
@RestController / @RequestMapping / @GetMapping 等
- 作用 : 这些是 Spring MVC 的注解,用于定义 RESTful Web 服务。Spring Boot 通过
spring-boot-starter-web自动配置了 Spring MVC,因此你可以直接使用这些注解来创建控制器。
扩展(自行了解):
1. @RestController:声明 RESTful 控制器
- 核心作用 :这是一个组合注解 ,它结合了
@Controller和@ResponseBody的功能。@Controller:标记一个类为 Spring MVC 的控制器,使其能够处理 HTTP 请求。@ResponseBody:指示方法的返回值应直接写入 HTTP 响应体(Response Body),而不是解析为视图名称。通常用于返回 JSON 或 XML 数据。
- 使用场景 :所有现代 RESTful API 的控制器类都应使用
@RestController。它明确表示该类的方法返回值将直接作为 API 的响应数据。
2. @RequestMapping:通用请求映射
-
核心作用 :将 HTTP 请求映射到控制器类或方法上。它可以指定请求的 URL 路径 、HTTP 方法 (GET, POST, PUT, DELETE 等)、请求参数 、请求头等条件。
-
常用属性 :
value或path:指定映射的 URL 路径(支持 Ant 风格和路径变量)。method:指定允许的 HTTP 方法(如RequestMethod.GET)。consumes:指定处理请求的媒体类型(Content-Type),如"application/json"。produces:指定响应的媒体类型(Accept),如"application/json"。
-
使用建议 :虽然功能强大,但在 Spring Boot 中,更推荐使用其衍生注解 (如
@GetMapping)来声明特定类型的请求,代码更简洁、意图更明确。@RequestMapping通常用于类级别定义公共路径前缀。 -
代码示例 :
java@RestController @RequestMapping(value = "/api/books", produces = "application/json") // 类级别:路径前缀和默认响应类型 public class BookController { // 使用衍生注解更清晰 @GetMapping public List<Book> getAllBooks() { ... } // 老式写法,效果同上,但不推荐 @RequestMapping(method = RequestMethod.GET) public List<Book> getAllBooksOld() { ... } // 复杂的映射条件 @RequestMapping(value = "/search", method = {RequestMethod.GET, RequestMethod.POST}, consumes = "application/json") public List<Book> searchBooks(@RequestBody SearchCriteria criteria) { ... } }
3. HTTP 方法特定的衍生注解(@GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping)
-
核心作用 :这些是
@RequestMapping(method = ...)的快捷方式,专门用于处理特定 HTTP 方法的请求。它们使代码更简洁、更符合 RESTful 风格。 -
各自用途 :
@GetMapping:处理 HTTP GET 请求,用于查询/获取资源。@PostMapping:处理 HTTP POST 请求,用于创建新资源。@PutMapping:处理 HTTP PUT 请求,用于完整更新资源(替换整个资源)。@PatchMapping:处理 HTTP PATCH 请求,用于部分更新资源。@DeleteMapping:处理 HTTP DELETE 请求,用于删除资源。
-
最佳实践 :强烈建议使用这些特定注解 ,而不是通用的
@RequestMapping。这能提高代码的可读性,并遵循 RESTful API 的设计原则(GET 获取、POST 创建、PUT 更新、DELETE 删除)。 -
综合示例(一个完整的 CRUD 控制器) :
java@RestController @RequestMapping("/api/products") public class ProductController { @GetMapping public List<Product> listProducts() { // 获取产品列表 return productService.findAll(); } @GetMapping("/{id}") public Product getProduct(@PathVariable Long id) { // 根据ID获取单个产品 return productService.findById(id); } @PostMapping @ResponseStatus(HttpStatus.CREATED) // 设置响应状态码为 201 Created public Product createProduct(@Valid @RequestBody Product product) { // 创建新产品,@Valid 用于触发JSR-303 Bean验证 return productService.create(product); } @PutMapping("/{id}") public Product updateProduct(@PathVariable Long id, @Valid @RequestBody Product product) { // 更新指定ID的产品 product.setId(id); return productService.update(product); } @DeleteMapping("/{id}") @ResponseStatus(HttpStatus.NO_CONTENT) // 设置响应状态码为 204 No Content public void deleteProduct(@PathVariable Long id) { // 删除产品 productService.delete(id); } }
4. 配套的常用参数绑定注解
Spring MVC 提供了丰富的注解,用于将 HTTP 请求中的不同部分绑定到控制器方法的参数上:
-
@PathVariable:绑定 URL 路径中的变量 (如/users/{id}中的{id})。 -
@RequestParam:绑定 URL 查询参数 (如/users?name=John&age=25中的name和age)。可以指定是否必需、默认值。java@GetMapping("/search") public List<User> searchUsers(@RequestParam String keyword, @RequestParam(defaultValue = "1") int page) { ... } -
@RequestBody:将 HTTP 请求体(通常是 JSON 或 XML)绑定到一个 Java 对象上。通常用于 POST/PUT 请求。 -
@RequestHeader:绑定 HTTP 请求头中的值。 -
@CookieValue:绑定 HTTP Cookie 的值。 -
@ModelAttribute:绑定请求参数到模型对象(常用于传统表单提交,在 RESTful API 中较少使用)。
5. 响应处理注解
-
@ResponseBody:已包含在@RestController中,单独使用较少。 -
@ResponseStatus:指定HTTP 响应状态码 。可以标注在方法或异常类上。java@PostMapping @ResponseStatus(HttpStatus.CREATED) // 成功创建资源,返回 201 public Product create(...) { ... } @ResponseStatus(HttpStatus.NOT_FOUND) // 当抛出此异常时,返回 404 public class ResourceNotFoundException extends RuntimeException { ... } -
ResponseEntity<T>:更灵活的响应封装类。可以同时控制响应体、状态码和响应头 。是构建精细控制 API 响应的首选方式。java@GetMapping("/{id}") public ResponseEntity<Product> getProduct(@PathVariable Long id) { Product product = productService.findById(id); if (product == null) { return ResponseEntity.notFound().build(); // 返回 404 } return ResponseEntity.ok() .header("Custom-Header", "value") .body(product); // 返回 200 和产品数据 }
6. Spring Boot 的自动配置支持
当你引入 spring-boot-starter-web 依赖后,Spring Boot 会自动配置:
DispatcherServlet:Spring MVC 的核心前端控制器,自动注册并映射到根路径 (/) 或通过spring.mvc.servlet.path自定义。- HTTP 消息转换器 :自动配置
Jackson2ObjectMapperBuilder和MappingJackson2HttpMessageConverter,支持 JSON 序列化/反序列化。如果 classpath 中有其他库(如 Gson、XML),也会自动配置相应的转换器。 - 静态资源处理 :自动映射
classpath:/static/,classpath:/public/等目录下的静态资源。 - 错误处理 :提供默认的
/error映射和BasicErrorController,并支持通过@ControllerAdvice进行全局异常处理。 - Web 服务器:内嵌 Tomcat(默认)、Jetty 或 Undertow。
总结 :@RestController、@RequestMapping 及其衍生注解是 Spring Boot 开发 Web 应用的基石。理解并熟练运用它们,结合 Spring Boot 的自动配置,可以让你快速构建出结构清晰、符合 RESTful 规范的 Web API。记住,@RestController 用于类,特定 HTTP 方法注解用于方法,再配合路径变量、请求参数和请求体绑定注解,就能覆盖绝大多数 Web 开发场景。
---------------------------------------------
条件满足
条件不满足
是,@ConditionalOnMissingBean 生效
否
主类标注 @SpringBootApplication
触发 @ComponentScan
扫描并注册项目中的 @Component, @Service 等
触发 @EnableAutoConfiguration
加载 spring.factories 中的自动配置类
自动配置类上的 @ConditionalOnXxx
创建默认 @Bean 定义
跳过该自动配置
Spring 容器合并所有 Bean 定义
开发者自定义 @Bean
覆盖同类型的默认 Bean?
默认配置被跳过
完成应用上下文启动
核心要点回顾:
@SpringBootApplication是入口,集成了配置、自动装配和组件扫描。@ConfigurationProperties是实现外部化、类型安全配置的核心。@ConditionalOnXxx系列注解是自动配置灵活性的保障,实现了"有则配置,无则跳过;用户定义,优先使用"的智能行为。- 理解这些注解如何协作,是深入掌握 Spring Boot 自动配置原理和进行高效定制开发的基础。
03、简述SpringBoot的自动配置原理,@EnableAutoConfiguration 注解的作用是什么?
Spring Boot 的自动配置(Auto-Configuration) 是其"约定大于配置"理念的核心实现,也是 Spring Boot 能够"开箱即用"的魔法所在。
3.1 自动配置的核心思想
自动配置的核心思想是:基于 classpath 中存在的依赖、已定义的 Bean 以及配置文件中的属性,自动推断并配置 Spring 应用所需的组件。【类路径扫描+条件化配置+自动配置类】
例如:
- 当你的 classpath 中有
spring-boot-starter-web依赖时,Spring Boot 会自动配置一个内嵌的 Tomcat 服务器和 Spring MVC 相关的 Bean(如DispatcherServlet、ViewResolver等)。 - 当 classpath 中有
spring-boot-starter-data-jpa和 H2 数据库驱动时,Spring Boot 会自动配置一个内存数据库的DataSource和 JPA 的EntityManagerFactory。
3.2 @EnableAutoConfiguration 注解的作用
@EnableAutoConfiguration 是 Spring Boot 自动配置的总开关 。它通常作为 @SpringBootApplication 组合注解的一部分出现在主类上。
工作原理:
- Spring Boot 在启动时,会扫描 classpath 下的
META-INF/spring.factories文件(Spring Boot 2.7 之前)或META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件(Spring Boot 2.7+)。 - 这些文件中列出了大量的自动配置类 (如
DataSourceAutoConfiguration、WebMvcAutoConfiguration、JacksonAutoConfiguration等)。 @EnableAutoConfiguration通过@Import(AutoConfigurationImportSelector.class)导入一个选择器,该选择器会读取这些文件,筛选出符合条件的自动配置类,并将它们导入到 Spring 容器中。
3.3 自动配置的执行流程
自动配置的执行遵循一个清晰的流程,确保配置的合理性和可覆盖性:
条件满足
条件不满足
应用启动,主类标注 @SpringBootApplication
包含 @EnableAutoConfiguration
AutoConfigurationImportSelector 开始工作
扫描 META-INF/spring.factories
或 AutoConfiguration.imports 文件
获取所有候选的自动配置类
对每个自动配置类进行条件检查
加载并应用该配置类
跳过该配置类
配置类中定义的 @Bean 方法被执行
Bean 被注册到 Spring 容器
应用启动完成,
所有自动配置的 Bean 可用
3.4 条件注解:
自动配置之所以智能,是因为它大量使用了 @Conditional 及其衍生注解(统称为条件注解)。这些注解决定了某个配置类或 Bean 定义是否应该生效。
核心条件注解:
-
@ConditionalOnClass:当 classpath 下存在指定的类时才生效。java@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class}) // 只有当 DataSource 类和 EmbeddedDatabaseType 类都存在时,该配置才生效 -
@ConditionalOnMissingBean:最关键的条件**。当 Spring 容器中不存在指定类型或名称的 Bean 时才生效 这实现了"用户配置优先"的原则。java@Bean @ConditionalOnMissingBean public DataSource dataSource() { // 只有当用户没有自己定义 DataSource Bean 时,这个默认的 HikariCP 数据源才会被创建 return new HikariDataSource(); } -
@ConditionalOnProperty:当指定的配置属性具有特定值(或存在)时才生效。java@ConditionalOnProperty(prefix = "spring.datasource", name = "url") // 只有当配置了 spring.datasource.url 属性时,该配置才生效 -
@ConditionalOnWebApplication/@ConditionalOnNotWebApplication:根据应用是否为 Web 应用来决定。 -
@ConditionalOnExpression:根据 SpEL 表达式的结果来决定。
3.6 如何查看和调试自动配置?
-
查看生效的自动配置 :
在应用启动时,添加
--debug参数:bashjava -jar your-app.jar --debug或者在
application.properties中设置:propertiesdebug=true启动日志中会输出两部分:
- Positive matches:条件满足,已生效的自动配置。
- Negative matches:条件不满足,未生效的自动配置及原因。
-
排除特定的自动配置 :
如果你不需要某个自动配置,可以排除它:exclude(直接指定要排除的自动 )
java@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) // 或者通过配置属性 // spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
3.7 自动配置原理总结
- 触发 :通过
@EnableAutoConfiguration注解(通常包含在@SpringBootApplication中)触发自动配置流程。 - 发现 :
AutoConfigurationImportSelector从spring.factories或AutoConfiguration.imports文件中加载所有候选的自动配置类。 - 过滤 :利用 条件注解(
@ConditionalOnXxx) 对每个自动配置类进行筛选。只有所有条件都满足的配置类才会被真正加载。 - 执行 :被选中的配置类(即
@Configuration类)中的@Bean方法被执行,向 Spring 容器注册 Bean。 - 覆盖 :
@ConditionalOnMissingBean是关键 。它确保了如果开发者已经在自己的@Configuration类中定义了同类型的 Bean,那么 Spring Boot 的默认配置就会跳过,从而实现"用户配置优先"。