跳到主要内容
Spring Boot 详解:核心原理与开发指南 | 极客日志
Java java
Spring Boot 详解:核心原理与开发指南 综述由AI生成 Spring Boot 框架的核心概念与开发实践。内容涵盖 Spring Boot 概述及其与 Spring 的区别,重点讲解了自动配置、启动器、嵌入式服务器及生产级特性。文章深入剖析了常用注解(如@Conditional、@ConfigurationProperties)、自动配置原理(@SpringBootApplication、spring.factories)、配置管理优先级、嵌入式服务器定制方法以及测试策略。旨在帮助开发者掌握 Spring Boot 的快速开发模式与底层机制,提升开发效率。
剑仙 发布于 2026/3/23 更新于 2026/5/1 4.1K 浏览概览
Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化 Spring 应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。Spring Boot 提供了一种新的编程范式,可以更加快速便捷地开发 Spring 项目,在开发过程当中可以专注于应用程序本身的功能开发,而无需在 Spring 配置上花太大的工夫。
Spring Boot 基于 Spring4 进行设计,继承了原有 Spring 框架的优秀基因。Spring Boot 准确的说并不是一个框架,而是一些类库的集合。maven 或者 gradle 项目导入相应依赖即可使用 Spring Boot,而无需自行管理这些类库的版本。
特点:
自动配置:Spring Boot 提供自动配置功能,根据项目的依赖和环境自动设置 Spring 应用程序,减少了手动配置的复杂度。
启动器:Spring Boot 提供'启动器'依赖集合,如 spring-boot-starter-web,简化了项目的依赖管理。
嵌入式服务器:Spring Boot 支持嵌入式服务器,如 Tomcat、Jetty 和 Undertow,使得应用程序可以独立运行,无需外部 Web 服务器。
生产级别的特性:Spring Boot 具备生产级别的功能,包括健康检查、应用监控、日志管理等。Actuator 模块可以轻松监控和管理应用程序。
无配置的约定:Spring Boot 遵循'无配置'的原则,使用合理的默认值和约定,减少需要编写的配置代码。
快速开发:Spring Boot 的项目结构和默认配置帮助开发者快速启动新项目。内置工具和插件支持开发、测试和部署。
与 Spring 的区别
Spring 提供了大量的子模块,如 Spring Core、Spring Web、Spring Data 等,但它们的配置复杂度较高,且需要开发者手动配置各类文件和依赖。Spring Boot 基于 Spring,目的是简化 Spring 应用的创建和配置。
Spring Boot 是对 Spring 的扩展,简化了 Spring 应用开发的过程,但仍然依赖 Spring 核心库。使用 Spring Boot 开发的应用实际上是基于 Spring 的,只是通过自动配置和内置依赖提升了开发效率。
Spring 和 Spring Boot 的主要区别在于配置和启动的复杂性。Spring 框架需要大量的手动配置,包括 XML 配置文件或 Java 配置类,配置过程较为繁琐且易出错。此外,Spring 应用程序通常需要部署到外部的 Web 服务器,并需要额外的步骤来启动和运行。
相比之下,Spring Boot 提供了自动配置功能,可以根据项目的依赖自动设置应用程序,极大地简化了配置工作。它还支持嵌入式服务器,使得应用程序能够独立运行,无需外部 Web 服务器,且可以通过 java -jar 命令直接启动。这些特点使得 Spring Boot 更加适合快速开发和部署应用程序。
创建 Spring Boot 项目
在 IDEA 中使用 Spring Initializr 快速创建一个 Spring Boot 项目。
选择所需的依赖。
Spring Boot 项目通常包括以下几个主要部分:
在 src/main/resources 目录下创建 application.properties 或 application.yml 文件来配置应用程序。示例配置如下:
主应用类通常位于项目的根包,并使用 @SpringBootApplication 注解。
创建一个 Controller 处理 HTTP 请求并返回响应。使用 @RestController 注解定义控制器,使用 @RequestMapping 或 @GetMapping 处理请求。
在 IDE 中运行,右击主应用类并选择'Run'。
通过浏览器输入 http://localhost:8081/api/hello 测试。
Spring Boot 常用注解
在 Spring Boot 开发中,常用的注解简化了配置和开发流程。
@Conditional:用于根据条件判断是否应用特定的配置。@Conditional 注解的核心是通过 Condition 接口的实现来控制 Bean 的创建。Spring 在启动时会检查这些条件,只有当所有条件都满足时,相关的 Bean 才会被注册到 Spring 容器中。
public class CustomCondition implements Condition {
{
context.getEnvironment().getProperty( );
.equals(property);
}
}
@Override
public
boolean
matches
(ConditionContext context, AnnotatedTypeMetadata metadata)
String
property
=
"custom.property"
return
"expectedValue"
@ConfigurationProperties:用于将配置文件中的属性映射到 Java 类中。这样,配置可以作为一个 Java Bean 进行管理,便于在应用中使用。
@ConfigurationProperties(prefix = "myapp")
public class MyAppProperties {
private String name;
private int maxAttempts;
}
@Value:从配置文件中注入值到字段,允许应用程序灵活地读取外部配置。
@Component
public class MyComponent {
@Value("${my.property}")
private String myProperty;
}
@Bean:在配置类中定义 Bean 方法,Spring 管理这些 Bean 的生命周期。
@Bean
public MyBean myBean () {
return new MyBean ();
}
@Configuration:标记 Spring 配置类,用于配置 Spring 容器、配置 Bean。
@Configuration
public class AppConfig {
@Bean
public MyBean myBean () {
return new MyBean ();
}
}
@Repository:标记 Spring 数据访问组件,用于数据持久化。
@Repository
public class MyRepository {
}
@Service:标记 Spring 业务组件,用于业务逻辑处理。
@Service
public class MyService {
}
@Component:标记 Spring 组件,使其能够被自动扫描和管理,@Component 为标记通用的 Spring 组件。
@Service
public class MyService {
private final MyRepository myRepository;
@Autowired
public MyService (MyRepository myRepository) {
this .myRepository = myRepository;
}
}
@Autowired:自动注入 Spring 管理的 Bean。可以用于构造函数、字段或 setter 方法。
@Service
public class MyService {
private final MyRepository myRepository;
@Autowired
public MyService (MyRepository myRepository) {
this .myRepository = myRepository;
}
}
@ResponseBody:将方法的返回值直接写入 HTTP 响应体中。常用于控制器方法,以使得返回的数据,通常是 JSON 或 XML,能够被自动序列化并发送给客户端。
@Controller
@ResponseBody
@RequestMapping("/api")
public class MyRestController {
@GetMapping("/info")
public MyResponseData getInfo () {
return new MyResponseData ("Alice" , 30 );
}
}
class MyResponseData {
private String name;
private int age;
public MyResponseData (String name, int age) {
this .name = name;
this .age = age;
}
}
@RequestBody:将 HTTP 请求体的内容绑定到方法参数上。通常用于 POST 请求,当请求的内容是 JSON、XML 或其他类型的数据时,可以通过 @RequestBody 注解将其自动转换为 Java 对象。
@RestController
public class MyRestController {
@PostMapping("/submit")
public String submitData (@RequestBody MyRequestData data) {
return "Data received: " + data.toString();
}
}
class MyRequestData {
private String name;
private int age;
}
@RequestMapping:映射 HTTP 请求到控制器的方法。支持不同的请求方法(GET、POST 等),其衍生注解为 @GetMapping、@PostMapping、@PutMapping、@DeleteMapping。
@RestController
public class MyController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String getHello () {
return "Hello, GET!" ;
}
}
@Controller:用于定义一个 SpringMVC 控制器类,它的主要目的是处理 Web 请求并返回视图,如 JSP、Thymeleaf 模板等。
@Controller
public class MyController {
@GetMapping("/home")
public String home () {
return "home" ;
}
}
@RestController:是一个组合注解,结合了 @Controller 和 @ResponseBody。用于定义控制器类,并将返回的对象自动转换为 JSON 或 XML 格式,简化了 RESTful API 的开发。
@RestController
@RequestMapping("/api")
public class MyController {
@GetMapping("/hello")
public String sayHello () {
return "Hello, World!" ;
}
}
@SpringBootApplication:标注在启动类上,它综合了 @Configuration、@EnableAutoConfiguration 和 @ComponentScan 注解,用于自动配置和组件扫描。
@SpringBootApplication
public class MyApplication {
public static void main (String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Spring Boot 自动配置 Spring Boot 的自动配置通过条件化配置和扫描机制来简化应用设置。应用启动时,Spring Boot 根据 spring.factories 文件中的配置自动加载所有标记为自动配置的类。每个自动配置类使用条件注解,如 @ConditionalOnClass、@ConditionalOnMissingBean 等,来判断是否应该应用特定的配置。这些注解帮助决定是否创建和配置 Bean。如果符合条件,Spring Boot 会自动生成所需的 Bean 实例并将其添加到应用上下文中。
其自动配置原理,是通过 @SpringBootApplication 注解,在启动时加载的。@SpringBootApplication 这个注解通常标注在启动类上:
@SpringBootApplication
public class SpringBootExampleApplication {
public static void main (String[] args) {
SpringApplication.run(SpringBootExampleApplication.class, args);
}
}
@SpringBootApplication 是一个复合注解,即由其他注解构成。核心注解是 @SpringBootConfiguration 和 @EnableAutoConfiguration。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)
})
public @interface SpringBootApplication {}
@SpringBootConfiguration @SpringBootConfiguration 核心注解是 @Configuration 的作用是将类标记为配置类,可以定义 @Bean 方法来创建和配置 Spring 容器中的 Bean。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {}
@Configuration 底层实现就是一个 Component。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component{}
@EnableAutoConfiguration @EnableAutoConfiguration 作用是启用 Spring Boot 的自动配置机制。它的核心是 @AutoConfigurationPackage 和 @Import({AutoConfigurationImportSelector.class})
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {}
@AutoConfigurationPackage 的核心是引入了一个 @Import(AutoConfigurationPackages.Registrar.class) 配置类,该类实现了 ImportBeanDefinitionRegistrar 接口。这个注解本身的含义就是将主配置类(@SpringBootApplication 标注的类)所在的包下面所有的组件都扫描到 Spring 容器中。
static class Registrar implements ImportBeanDefinitionRegistrar , DeterminableImports {
@Override
public void registerBeanDefinitions (AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
register(registry, new PackageImports (metadata).getPackageNames().toArray(new String [0 ]));
}
@Override
public Set<Object> determineImports (AnnotationMetadata metadata) {
return Collections.singleton(new PackageImports (metadata));
}
}
AutoConfigurationImportSelector 类的作用是通过扫描 spring.factories 文件,加载所有自动配置类。
protected List<String> getCandidateConfigurations (AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct." );
return configurations;
}
但是 spring.factories 包含了很多类,并不是全部都加载的,在某些类里面,是有一个条件 @ConditionalOnXXX 注解,只有当这个注解上的条件满足才会加载。如 SpringApplicationAdminJmxAutoConfiguration。
@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter(JmxAutoConfiguration.class)
@ConditionalOnProperty(prefix = "spring.application.admin", value = "enabled", havingValue = "true", matchIfMissing = false)
public class SpringApplicationAdminJmxAutoConfiguration {}
当一个类使用 @SpringBootApplication 注解时,Spring Boot 会自动进行一系列配置,让应用快速启动并运行。这个注解包含了 @SpringBootConfiguration,相当于告诉 Spring 这是一个配置类,就像使用了 @Configuration 一样。@Configuration 的作用是将类标记为配置类,这个配置类可以定义 @Bean 方法来创建和配置 Spring 容器中的 Bean。同时,@EnableAutoConfiguration 启用了 Spring Boot 的自动配置功能,Spring Boot 会根据项目中的依赖,自动配置很多常用的 Spring 组件,这样就不需要手动配置它们。这个自动配置的过程是通过扫描 spring.factories 文件中的自动配置类来实现的。另外,@ComponentScan 让 Spring 自动扫描当前包及其子包下的所有组件,比如标注了 @Component、@Service、@Repository 和 @Controller 的类,并把它们注册到 Spring 容器中。因此,把应用的主类放在根包中,Spring Boot 就会自动扫描并加载所有需要的组件和配置,让你可以专注于编写业务代码,而不用担心复杂的配置细节。Spring Boot 通过这一系列自动化的配置和扫描机制,简化了开发和配置的工作量,让应用能够快速启动并运行。
Spring Boot 配置管理 Spring Boot 支持 application.properties 和 application.yml 两种格式的配置文件,通常放置在 src/main/resources 目录下。
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: secret
myapp:
name: MyApplication
maxAttempts: 5
如果想要读取配置,可以使用 @Value 注解或者 @ConfigurationProperties 注解。使用 @ConfigurationProperties 注解将配置文件中的属性绑定到 Java 类中,能够将复杂配置集中管理。
@ConfigurationProperties(prefix = "myapp")
public class MyAppProperties {
private String name;
private int maxAttempts;
}
使用 @Value 注解可以将配置文件中的单个属性注入到 Bean 的字段中。
@Component
public class MyComponent {
@Value("${myapp.name}")
private String appName;
}
但需要注意的是,并不是在配置文件中配置了,就一定会加载,Spring Boot 配置的加载优先级由高到低依为:
系统属性:系统属性通过 System.setProperty 方法设置,优先级最低。这些属性可以在应用启动时或者在 JVM 启动时通过 -D 参数设置,虽然优先级低于其他配置源,但它们仍然会被加载。
System.setProperty("server.port" , "9090" );
application.properties 或 application.yml 文件:这些文件通常位于 src/main/resources 目录下,提供了默认的配置。这些配置会被加载到应用程序上下文中,但它们的优先级低于命令行参数。
环境变量:环境变量的配置优先级低于命令行参数,但高于 application.properties 和 application.yml 文件。环境变量通常用于在操作系统级别定义配置,例如在生产环境中。
命令行参数:命令行参数的配置优先级最高。当你启动 Spring Boot 应用时,可以通过命令行传递配置参数,这些参数会覆盖其他来源的配置。
java -jar myapp.jar -Dserver.port=9090
除此之外可以使用 application-{profile}.properties 或 application-{profile}.yml 文件为不同的环境提供特定的配置。且通过设置 spring.profiles.active 属性来激活特定的环境配置。
server.port=8081 # application.properties
spring.profiles.active=dev
有时需要根据特定条件加载不同的配置文件。这种需求通常出现在环境配置、特性开关或者动态调整配置的场景中,就可以通过环境控制的方式来实现。
application-prod.properties
server.port=80
myapp.feature=disabled
application-dev.properties
server.port=8081
myapp.feature=enabled
在 application.properties 中激活特定的 profile:
spring.profiles.active=dev
这样 Spring Boot 会根据激活的 profile 加载对应的配置文件。
其实使用 @Profile 注解也能实现环境控制,@Profile 注解允许在特定的 profile 激活时创建 Bean 或配置类。结合 @Configuration 使用,可以在不同的环境中加载不同的 Bean 配置。
@Configuration
@Profile("dev")
public class DevConfiguration {
@Bean
public MyBean myBean () {
return new MyBean ("Development Bean" );
}
}
或者使用 @Conditional,@Conditional 注解允许根据条件决定是否加载配置。可以结合自定义条件来实现复杂的条件加载逻辑。
public class OnCustomCondition implements Condition {
@Override
public boolean matches (ConditionContext context, AnnotatedTypeMetadata metadata) {
return "true" .equals(System.getProperty("custom.condition" ));
}
}
@Configuration
@Conditional(OnCustomCondition.class)
public class CustomConditionConfiguration {
@Bean
public CustomBean customBean () {
return new CustomBean ();
}
}
Spring Boot 嵌入式服务器 Spring Boot 提供了内置的 Web 服务器,如 Tomcat、Jetty 和 Undertow,嵌入式的服务器功能使得构建和运行 JavaWeb 应用变得更加简单。
有了嵌入式的服务器就不需要将应用程序打包为 WAR 包并部署到外部服务器,直接打包为 JAR 文件即可运行。而且运行和调试 Web 应用时不需要管理服务器的独立生命周期,而且内置服务器通常比外部服务器占用的资源少,启动速度更快。
Spring Boot 默认内置 Tomcat 作为嵌入式服务器。如果没有特别修改,应用将使用 Tomcat。
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-web</artifactId >
</dependency >
如果要使用 Jetty 代替 Tomcat,需要在 pom.xml 中排除 Tomcat 并添加 Jetty 依赖。
<dependencies >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-web</artifactId >
<exclusions >
<exclusion >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-tomcat</artifactId >
</exclusion >
</exclusions >
</dependency >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-jetty</artifactId >
</dependency >
</dependencies >
内置的服务器实际上,Spring Boot 是通过自动配置机制来简化 Web 服务器的配置。应用启动时,Spring Boot 会自动检测类路径中的依赖,并根据它们自动配置 Web 服务器。自动配置类位于 org.springframework.boot.autoconfigure.web.servlet 包中,例如 TomcatServletWebServerFactory、JettyServletWebServerFactory 和 UndertowServletWebServerFactory。
@Configuration
@ConditionalOnClass(Servlet.class)
@ConditionalOnMissingBean(ServletWebServerFactory.class)
@EnableConfigurationProperties(WebServerProperties.class)
public class TomcatServletWebServerFactoryConfiguration {
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory (WebServerProperties properties) {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory ();
return factory;
}
}
Spring Boot 使用 ServletWebServerFactory 接口及其实现,例如 TomcatServletWebServerFactory 来创建内嵌的 Web 服务器。ServletWebServerFactory 提供了创建和配置 Web 服务器的能力。当应用启动时,Spring Boot 会创建一个 ServletWebServerFactory 实现的实例,并使用该实例启动 Web 服务器。
@Bean
public ServletWebServerFactory servletContainer () {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory ();
factory.setPort(8080 );
return factory;
}
可以通过实现 TomcatServletWebServerFactory、JettyServletWebServerFactory 或 UndertowServletWebServerFactory 接口来自定义嵌入式服务器的配置。
@Configuration
public class CustomTomcatFactory extends TomcatServletWebServerFactory {
@Bean
@Override
public ServletWebServerFactory servletContainer () {
return new TomcatServletWebServerFactory () {
@Override
protected Tomcat getTomcatEmbeddedServletContainer () {
Tomcat tomcat = super .getTomcatEmbeddedServletContainer();
tomcat.getConnector().setAttribute("maxThreads" , 200 );
return tomcat;
}
};
}
}
Spring Boot 测试 测试是保证应用正确性和稳定性的关键部分,Spring Boot 提供了多种测试工具和注解,以便于进行集成测试、单元测试和功能测试。
导入测试依赖。org.springframework.boot spring-boot-starter-test test org.junit.jupiter junit-jupiter-api test org.junit.jupiter junit-jupiter-engine test
编写测试类。通常,测试类放在与主代码相同的包结构中的 src/test/java 目录下。
@SpringBootTest
public class MyServiceTests {
@Autowired
private MyService myService;
@Test
public void testPerformAction () {
String result = myService.performAction();
assertEquals("ExpectedResult" , result);
}
}
一个最简单的单元测试就创建完毕了。在实际测试中,有时候需要测试场景中加载配置,@TestConfiguration 注解用于创建专门的测试配置类。这些配置类仅在测试上下文中有效,用于提供测试所需的额外 Bean。
@TestConfiguration
public class TestConfig {
@Bean
public TestService testService () {
return new TestService ();
}
}
@SpringBootTest
@Import(TestConfig.class)
public class ServiceTests {
@Autowired
private TestService testService;
@Test
public void testService () {
}
}
除了这些,还能使用 @ExtendWith 和自定义扩展,自定义扩展来添加额外的功能,如测试环境准备、清理操作等。
public class CustomExtension implements TestInstancePostProcessor , TestExecutionExceptionHandler {
@Override
public void postProcessTestInstance (Object testInstance, ExtensionContext context) {
}
@Override
public void handleTestExecutionException (ExtensionContext context, Throwable throwable) throws Throwable {
}
}
@ExtendWith(CustomExtension.class)
public class CustomExtensionTests {
@Test
public void testWithCustomExtension () {
}
}
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online