Spring Boot 深度解析

一、Spring Boot 核心定位

Spring Boot 是基于 Spring 框架的快速开发脚手架 ,核心目标是简化Spring应用的初始化搭建和开发过程,解决了传统Spring应用「配置繁琐、依赖管理复杂、部署麻烦」的痛点。

  • 核心理念:约定优于配置(Convention Over Configuration),通过默认配置减少开发者的配置工作;
  • 核心优势:
    1. 自动配置 :根据引入的依赖自动配置Spring组件(如引入spring-boot-starter-web自动配置Spring MVC);
    2. 起步依赖 :将常用依赖打包为starter,一键引入即可使用(如spring-boot-starter-web包含Spring MVC、Tomcat、Jackson等);
    3. 嵌入式容器:内置Tomcat/Jetty/Undertow,无需手动部署WAR包,可直接运行JAR包;
    4. 简化监控 :通过spring-boot-starter-actuator快速实现应用监控;
    5. 无代码生成/无XML配置:纯Java配置,开箱即用;
  • 应用场景:所有Spring生态的应用开发(微服务、单体应用),是Spring Cloud微服务架构的基础。

二、Spring Boot 核心架构与自动配置原理

2.1 核心架构分层

Spring Boot应用
核心启动层(SpringApplication)
自动配置层(AutoConfiguration)
起步依赖层(Starter)
嵌入式容器层(Tomcat/Jetty)
Spring MVC自动配置(WebMvcAutoConfiguration)
数据源自动配置(DataSourceAutoConfiguration)
事务自动配置(TransactionAutoConfiguration)
spring-boot-starter-web
spring-boot-starter-data-jpa
spring-boot-starter-security
TomcatAutoConfiguration

2.2 自动配置核心原理

自动配置是Spring Boot最核心的特性,也是其与传统Spring应用的核心区别,底层基于「条件注解 + 类路径扫描 + 动态Bean注册」实现。

2.2.1 自动配置核心注解

注解 作用 示例
@SpringBootApplication 核心注解,整合3个关键注解:@SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan 标注在启动类上
@EnableAutoConfiguration 开启自动配置,触发Spring Boot扫描并加载自动配置类 核心底层注解
@AutoConfiguration Spring Boot 2.7+替代@Configuration的自动配置注解,控制配置加载顺序 @AutoConfiguration(after = WebMvcAutoConfiguration.class)
@Conditional 条件注解父类,满足指定条件才加载Bean -
@ConditionalOnClass 类路径存在指定类时生效 @ConditionalOnClass({DispatcherServlet.class})
@ConditionalOnMissingClass 类路径不存在指定类时生效 -
@ConditionalOnBean 容器中存在指定Bean时生效 -
@ConditionalOnMissingBean 容器中不存在指定Bean时生效(允许自定义覆盖默认配置) @ConditionalOnMissingBean(HandlerMapping.class)
@ConditionalOnProperty 配置文件中存在指定属性时生效 @ConditionalOnProperty(prefix = "spring.mvc", name = "enabled", havingValue = "true")

2.2.2 自动配置核心流程

步骤1:启动类触发自动配置
java 复制代码
// Spring Boot启动类核心代码
@SpringBootApplication
public class SpringBootDemoApplication {
    public static void main(String[] args) {
        // 核心方法:启动Spring Boot应用
        SpringApplication.run(SpringBootDemoApplication.class, args);
    }
}

// @SpringBootApplication注解源码(核心拆解)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration // 等价于@Configuration,标记配置类
@EnableAutoConfiguration // 开启自动配置
@ComponentScan(excludeFilters = { // 组件扫描
    @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)
})
public @interface SpringBootApplication {
    // 排除指定自动配置类
    Class<?>[] exclude() default {};
    // 排除指定自动配置类(通过类名)
    String[] excludeName() default {};
    // 组件扫描路径
    String[] scanBasePackages() default {};
}
步骤2:@EnableAutoConfiguration 核心逻辑
java 复制代码
// @EnableAutoConfiguration注解源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage // 自动配置包扫描(默认扫描启动类所在包)
@Import(AutoConfigurationImportSelector.class) // 导入自动配置选择器
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
    Class<?>[] exclude() default {};
    String[] excludeName() default {};
}

// AutoConfigurationImportSelector核心方法:加载自动配置类
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
    if (!isEnabled(annotationMetadata)) {
        return NO_IMPORTS;
    }
    // 1. 加载META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件
    AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
    return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

// 加载自动配置类的核心方法
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
    if (!isEnabled(annotationMetadata)) {
        return EMPTY_ENTRY;
    }
    AnnotationAttributes attributes = getAttributes(annotationMetadata);
    // 核心:从META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports加载所有自动配置类全限定名
    List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
    // 去重、排除指定类、过滤不满足条件的配置类
    configurations = removeDuplicates(configurations);
    Set<String> exclusions = getExclusions(annotationMetadata, attributes);
    checkExcludedClasses(configurations, exclusions);
    configurations.removeAll(exclusions);
    configurations = getConfigurationClassFilter().filter(configurations);
    fireAutoConfigurationImportEvents(configurations, exclusions);
    return new AutoConfigurationEntry(configurations, exclusions);
}
步骤3:自动配置类的加载与生效
  • Spring Boot启动时,会扫描META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件(Spring Boot 2.7+),该文件包含所有自动配置类的全限定名;
  • 每个自动配置类(如WebMvcAutoConfiguration)通过@Conditional系列注解判断是否生效,例如:
java 复制代码
// WebMvcAutoConfiguration(Spring MVC自动配置类)核心源码
@AutoConfiguration(after = { DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class })
@ConditionalOnWebApplication(type = Type.SERVLET) // 仅Servlet Web应用生效
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class }) // 类路径存在这些类才生效
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class) // 容器中不存在该类才生效(避免自定义配置被覆盖)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
public class WebMvcAutoConfiguration {

    // 配置视图解析器(Thymeleaf/JSP)
    @Bean
    @ConditionalOnMissingBean // 自定义ViewResolver会覆盖默认配置
    public InternalResourceViewResolver defaultViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix(this.mvcProperties.getView().getPrefix());
        resolver.setSuffix(this.mvcProperties.getView().getSuffix());
        return resolver;
    }

    // 配置RequestMappingHandlerMapping(Spring MVC核心组件)
    @Bean
    @ConditionalOnMissingBean
    public RequestMappingHandlerMapping requestMappingHandlerMapping(```) {
        RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
        // 省略配置逻辑```
        return mapping;
    }

    // 配置RequestMappingHandlerAdapter
    @Bean
    @ConditionalOnMissingBean
    public RequestMappingHandlerAdapter requestMappingHandlerAdapter(```) {
        // 省略配置逻辑```
        return adapter;
    }
}

2.3 Spring Boot 启动流程(核心步骤)

  1. 初始化SpringApplication:解析启动类、设置应用类型(Servlet/Reactive)、加载初始化器和监听器;
  2. 加载环境配置:读取application.yml/application.properties、命令行参数、系统属性等;
  3. 创建ApplicationContext:根据应用类型创建AnnotationConfigServletWebServerApplicationContext(Servlet应用);
  4. 刷新容器
    • 执行BeanFactoryPostProcessor;
    • 注册BeanPostProcessor;
    • 初始化MessageSource;
    • 初始化事件多播器;
    • 初始化嵌入式Servlet容器(Tomcat);
    • 注册并初始化所有Bean;
  5. 启动嵌入式容器:启动Tomcat/Jetty,绑定端口;
  6. 执行启动后处理器:触发ApplicationReadyEvent事件,应用启动完成。

三、Spring Boot 核心功能解析

3.1 内嵌Tomcat运行服务的实现原理

Spring Boot实现内嵌Tomcat运行服务的核心逻辑是:通过自动配置创建Tomcat容器实例 → 将Spring MVC核心Servlet(DispatcherServlet)注册到Tomcat → 启动Tomcat并绑定端口监听请求,整个过程无需手动部署WAR包,完全由Spring Boot自动完成。

步骤1:引入内嵌Tomcat依赖(基础前提)

Spring Boot的spring-boot-starter-web起步依赖会自动引入内嵌Tomcat的核心依赖,无需手动添加Tomcat相关jar包。

关键依赖(Maven)
xml 复制代码
<!-- spring-boot-starter-web 间接引入tomcat依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- 其内部依赖的tomcat核心包(无需手动引入) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-websocket</artifactId>
</dependency>

步骤2:自动配置Tomcat容器工厂(核心触发)

Spring Boot通过TomcatServletWebServerFactoryAutoConfiguration自动配置类,创建Tomcat容器的工厂类TomcatServletWebServerFactory,这是创建Tomcat实例的核心入口。

核心源码:TomcatServletWebServerFactoryAutoConfiguration
java 复制代码
// 仅在Servlet环境且存在Tomcat类时生效
@AutoConfiguration
@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
public class TomcatServletWebServerFactoryAutoConfiguration {

    // 创建Tomcat容器工厂Bean(核心)
    @Bean
    public TomcatServletWebServerFactory tomcatServletWebServerFactory(
            ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers,
            ObjectProvider<TomcatContextCustomizer> contextCustomizers,
            ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        // 应用自定义配置(如端口、线程池等)
        factory.getTomcatConnectorCustomizers().addAll(connectorCustomizers.orderedStream().toList());
        factory.getTomcatContextCustomizers().addAll(contextCustomizers.orderedStream().toList());
        factory.getTomcatProtocolHandlerCustomizers().addAll(protocolHandlerCustomizers.orderedStream().toList());
        return factory;
    }
}

关键说明

  • @ConditionalOnClass:确保类路径存在Tomcat核心类时才生效;
  • TomcatServletWebServerFactory:Tomcat容器的工厂类,负责创建TomcatWebServer(封装Tomcat实例的类)。

步骤3:ApplicationContext刷新时创建Tomcat容器

Spring Boot启动的核心阶段是ApplicationContextrefresh()方法,对于Web应用(ServletWebServerApplicationContext),会在刷新过程中调用createWebServer()方法创建Tomcat容器。

核心源码:ServletWebServerApplicationContext
java 复制代码
public class ServletWebServerApplicationContext extends GenericWebApplicationContext implements ConfigurableWebServerApplicationContext {

    private volatile WebServer webServer; // 封装Tomcat实例的对象

    @Override
    protected void onRefresh() {
        super.onRefresh();
        try {
            // 核心方法:创建WebServer(即Tomcat容器)
            createWebServer();
        } catch (Throwable ex) {
            throw new ApplicationContextException("Unable to start web server", ex);
        }
    }

    private void createWebServer() {
        WebServer webServer = this.webServer;
        ServletContext servletContext = getServletContext();
        if (webServer == null && servletContext == null) {
            // 1. 获取步骤2中创建的TomcatServletWebServerFactory
            ServletWebServerFactory factory = getWebServerFactory();
            // 2. 工厂创建TomcatWebServer(核心)
            this.webServer = factory.getWebServer(getSelfInitializer());
            getBeanFactory().registerSingleton("webServerGracefulShutdown",
                    new WebServerGracefulShutdownLifecycle(this.webServer));
            getBeanFactory().registerSingleton("webServerStartStop",
                    new WebServerStartStopLifecycle(this, this.webServer));
        } else if (servletContext != null) {
            try {
                getSelfInitializer().onStartup(servletContext);
            } catch (ServletException ex) {
                throw new ApplicationContextException("Cannot initialize servlet context", ex);
            }
        }
        initPropertySources();
    }
}

关键说明

  • onRefresh():ApplicationContext刷新时触发,是创建Web容器的核心时机;
  • factory.getWebServer():调用TomcatServletWebServerFactory的方法创建TomcatWebServer(Tomcat容器实例)。

步骤4:TomcatWebServer初始化Tomcat实例

TomcatServletWebServerFactorygetWebServer()方法会创建Tomcat实例,配置连接器(Connector)、引擎(Engine)、主机(Host)、上下文(Context)等核心组件。

核心源码:TomcatServletWebServerFactory
java 复制代码
public class TomcatServletWebServerFactory extends AbstractServletWebServerFactory {

    @Override
    public WebServer getWebServer(ServletContextInitializer```initializers) {
        // 1. 创建Tomcat核心实例
        org.apache.catalina.startup.Tomcat tomcat = new org.apache.catalina.startup.Tomcat();
        
        // 2. 配置Tomcat临时目录
        File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
        tomcat.setBaseDir(baseDir.getAbsolutePath());
        
        // 3. 创建连接器(Connector),绑定配置的端口(默认8080)
        Connector connector = new Connector(this.protocol);
        connector.setThrowOnFailure(true);
        tomcat.getService().addConnector(connector);
        customizeConnector(connector); // 应用端口、编码等配置
        tomcat.setConnector(connector);
        tomcat.getHost().setAutoDeploy(false);
        
        // 4. 创建Tomcat上下文(Context),对应Web应用的上下文路径
        prepareContext(tomcat.getHost(), initializers);
        
        // 5. 创建并返回TomcatWebServer(封装Tomcat实例)
        return new TomcatWebServer(tomcat, getPort() >= 0, getShutdown());
    }
}
核心源码:TomcatWebServer(Tomcat实例封装)
java 复制代码
public class TomcatWebServer implements WebServer {

    private final org.apache.catalina.startup.Tomcat tomcat; // 原生Tomcat实例
    private final boolean autoStart;

    public TomcatWebServer(org.apache.catalina.startup.Tomcat tomcat, boolean autoStart) {
        this.tomcat = tomcat;
        this.autoStart = autoStart;
        initialize(); // 初始化Tomcat
    }

    private void initialize() throws WebServerException {
        synchronized (this.monitor) {
            try {
                // 配置Tomcat引擎
                addInstanceIdToEngineName();

                // 启动Tomcat(核心)
                this.tomcat.start();

                // 等待Tomcat启动完成,确保连接器监听端口
                startDaemonAwaitThread();
            } catch (Exception ex) {
                stopSilently();
                destroySilently();
                throw new WebServerException("Unable to start embedded Tomcat", ex);
            }
        }
    }

    @Override
    public void start() throws WebServerException {
        synchronized (this.monitor) {
            if (this.started) {
                return;
            }
            // 启动Tomcat(autoStart=true时会自动调用)
            this.tomcat.start();
            this.started = true;
        }
    }
}

关键说明

  • TomcatWebServer封装了原生Tomcat实例,负责Tomcat的启动、停止;
  • tomcat.start():调用原生Tomcat的启动方法,启动连接器监听端口。

步骤5:注册DispatcherServlet到Tomcat

Spring MVC的核心Servlet(DispatcherServlet)会被注册到Tomcat的ServletContext中,绑定默认的/路径,接收所有请求。

核心源码:DispatcherServletAutoConfiguration
java 复制代码
@AutoConfiguration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
public class DispatcherServletAutoConfiguration {

    // 注册DispatcherServlet Bean
    @Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
    public DispatcherServlet dispatcherServlet(DispatcherServletProperties properties) {
        DispatcherServlet dispatcherServlet = new DispatcherServlet();
        dispatcherServlet.setDispatchOptionsRequest(properties.isDispatchOptionsRequest());
        dispatcherServlet.setDispatchTraceRequest(properties.isDispatchTraceRequest());
        // 省略其他配置```
        return dispatcherServlet;
    }

    // 将DispatcherServlet注册到Tomcat的ServletContext
    @Bean
    public DispatcherServletRegistrationBean dispatcherServletRegistrationBean(
            DispatcherServlet dispatcherServlet, WebMvcProperties webMvcProperties) {
        DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(
                dispatcherServlet, webMvcProperties.getServlet().getPath());
        registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
        registration.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup());
        if (webMvcProperties.getServlet().getMultipart() != null) {
            registration.setMultipartConfig(getMultipartConfig(webMvcProperties));
        }
        return registration;
    }
}

关键说明

  • DispatcherServletRegistrationBean:负责将DispatcherServlet注册到Tomcat的ServletContext;
  • 默认映射路径为/:所有请求都会被DispatcherServlet接收,然后转发到对应的Controller。

步骤6:Tomcat启动完成,监听端口处理请求

Tomcat启动后,连接器(Connector)会监听配置的端口(默认8080),当客户端发送请求时:

  1. Tomcat的连接器接收请求;
  2. 请求被转发到DispatcherServlet;
  3. DispatcherServlet按照Spring MVC的流程处理请求(匹配Controller、执行业务逻辑、返回响应);
  4. Tomcat将响应返回给客户端。

Spring Boot中内嵌Tomcat的启动是:Spring Boot应用上下文(ApplicationContext)执行refresh()刷新操作时,在onRefresh()方法中触发createWebServer(),最终在TomcatWebServer初始化阶段调用原生Tomcat的start()方法完成启动

3.2 配置管理

3.2.1 配置文件类型

  • 核心文件:application.properties / application.yml(优先级:yml > properties);
  • 多环境配置
    • application-dev.yml(开发环境);
    • application-test.yml(测试环境);
    • application-prod.yml(生产环境)。

3.2.2 激活多环境

yaml 复制代码
# application.yml
spring:
  profiles:
    active: dev # 激活开发环境
---
spring:
  config:
    activate:
      on-profile: dev
server:
  port: 8080
logging:
  level:
    root: DEBUG
---
spring:
  config:
    activate:
      on-profile: prod
server:
  port: 80
logging:
  level:
    root: INFO

3.2.3 配置绑定(@ConfigurationProperties)

java 复制代码
// 绑定配置文件中的属性
@Configuration
@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private String name;
    private String version;
    private Database database;

    // 静态内部类绑定嵌套属性
    public static class Database {
        private String url;
        private String username;
        private String password;
        
        // getter/setter
    }
    
    // getter/setter
}

// 配置文件(application.yml)
app:
  name: spring-boot-demo
  version: 1.0.0
  database:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: 123456

3.3 嵌入式容器

3.3.1 默认容器(Tomcat)配置

yaml# 复制代码
server:
  port: 8080# 端口
  servlet:
    context-path: /demo# 上下文路径
  tomcat:
    uri-encoding: UTF-8# URI编码
    max-threads: 200# 最大线程数
    min-spare-threads: 10# 最小空闲线程数
    basedir: tomcat-temp# Tomcat临时目录

3.3.2 切换容器(如Jetty)

xml 复制代码
<!-- pom.xml 排除Tomcat,引入Jetty -->
<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>

3.4 应用监控(Actuator)

3.4.1 核心依赖

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

3.4.2 核心配置

yaml# 复制代码
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,beans,env# 暴露的端点
      base-path: /actuator# 监控端点根路径
  endpoint:
    health:
      show-details: always# 显示健康检查详细信息
    metrics:
      enabled: true
  metrics:
    tags:
      application: spring-boot-demo# 指标标签

3.4.3 常用端点

端点 功能
/actuator/health 应用健康状态
/actuator/info 应用自定义信息
/actuator/metrics 应用指标(JVM、CPU、内存)
/actuator/beans 容器中所有Bean信息
/actuator/env 环境配置信息
/actuator/mappings Spring MVC请求映射信息

四、Spring Boot 与 Spring MVC 整合实战

4.1 基础整合

4.1.1 核心依赖

xml 复制代码
<!-- pom.xml -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.0</version>
    <relativePath/>
</parent>

<<dependencies>
    <!-- Web Starter(自动包含Spring MVC、Tomcat、Jackson) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- 测试依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</</dependencies>

4.1.2 启动类

java 复制代码
@SpringBootApplication
public class SpringMvcBootApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringMvcBootApplication.class, args);
    }
}

4.1.3 控制器(Spring MVC)

java 复制代码
@RestController
@RequestMapping("/user")
public class UserController {
    
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = new User();
        user.setId(id);
        user.setName("Spring Boot + MVC");
        user.setAge(20);
        return ResponseEntity.ok(user);
    }
    
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        user.setId(100L);
        return ResponseEntity.status(HttpStatus.CREATED).body(user);
    }
}

// 实体类
public class User {
    private Long id;
    private String name;
    private Integer age;
    
    // getter/setter/toString
}

4.1.4 配置文件(application.yml)

yaml 复制代码
server:
  port: 8080
  servlet:
    context-path: /demo
# Spring MVC配置
spring:
  mvc:
    servlet:
      load-on-startup: 1# 立即加载DispatcherServlet
    format:
      date: yyyy-MM-dd HH:mm:ss# 日期格式化
  web:
    resources:
      static-locations: classpath:/static/,classpath:/public/# 静态资源路径

4.2 自定义Spring MVC配置

4.2.1 扩展WebMvcConfigurer

java 复制代码
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    
    // 1. 自定义拦截器
    @Bean
    public LoginInterceptor loginInterceptor() {
        return new LoginInterceptor();
    }
    
    // 注册拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor())
                .addPathPatterns("/api/**")
                .excludePathPatterns("/api/login");
    }
    
    // 2. 自定义消息转换器(如FastJson替换Jackson)
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 移除默认Jackson转换器
        converters.removeIf(converter -> converter instanceof MappingJackson2HttpMessageConverter);
        
        // 添加FastJson转换器
        FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteMapNullValue);
        fastJsonConverter.setFastJsonConfig(fastJsonConfig);
        converters.add(fastJsonConverter);
    }
    
    // 3. 自定义视图解析器(Thymeleaf)
    @Bean
    public ThymeleafViewResolver thymeleafViewResolver(ITemplateResolver templateResolver) {
        ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setTemplateResolver(templateResolver);
        resolver.setCharacterEncoding("UTF-8");
        return resolver;
    }
    
    // 4. 跨域配置
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOriginPatterns("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

4.2.2 完全自定义Spring MVC配置(慎用)

若需要完全替换Spring Boot的默认MVC配置,可添加@EnableWebMvc注解(会禁用自动配置):

java 复制代码
@Configuration
@EnableWebMvc // 禁用Spring Boot的WebMvcAutoConfiguration
public class FullWebMvcConfig implements WebMvcConfigurer {
    // 需手动配置所有Spring MVC组件(HandlerMapping、HandlerAdapter等)
}

4.3 全局异常处理(Spring Boot + MVC)

java 复制代码
@RestControllerAdvice
public class GlobalExceptionHandler {
    
    // 处理参数绑定异常
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleValidException(MethodArgumentNotValidException e) {
        String message = e.getBindingResult().getFieldError().getDefaultMessage();
        ErrorResponse error = new ErrorResponse(400, "参数错误", message);
        return ResponseEntity.badRequest().body(error);
    }
    
    // 处理业务异常
    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException e) {
        ErrorResponse error = new ErrorResponse(e.getCode(), "业务异常", e.getMessage());
        return ResponseEntity.status(e.getCode()).body(error);
    }
    
    // 处理所有未捕获异常
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleException(Exception e) {
        log.error("系统异常", e);
        ErrorResponse error = new ErrorResponse(500, "服务器内部错误", "系统繁忙,请稍后重试");
        return ResponseEntity.status(500).body(error);
    }
    
    // 错误响应实体
    @Data
    @AllArgsConstructor
    public static class ErrorResponse {
        private int code;
        private String type;
        private String message;
    }
}

五、Spring Boot 高级特性

5.1 外部化配置优先级

Spring Boot加载配置的优先级(从高到低):

  1. 命令行参数(如java -jar app.jar --server.port=8081);
  2. 系统环境变量;
  3. 应用外部的application-{profile}.yml;
  4. 应用内部的application-{profile}.yml;
  5. 应用外部的application.yml;
  6. 应用内部的application.yml;
  7. @PropertySource注解加载的配置;
  8. 默认配置(Spring Boot自动配置)。

5.2 自定义启动器Banner

  1. 在resources目录下创建banner.txt文件;

  2. 写入自定义Banner(可通过Banner生成工具生成):


    | _ \ | | | | | | | | ()
    | |
    ) | __ | || || | ___ | | _ _ __
    | _ < / ` | __| __| |/ _ / | ' | | '
    | |
    ) | (
    | | |
    | || | _/_ \ | | | | |) |
    |/ _,|_|_||_||/| ||| .__/
    | |
    |
    |
    :: Spring Boot :: (3.2.0)

5.3 异步处理

5.3.1 异步控制器

java 复制代码
@RestController
@RequestMapping("/async")
public class AsyncController {
    
    @Autowired
    private AsyncService asyncService;
    
    // 异步请求(返回Callable)
    @GetMapping("/callable")
    public Callable<ResponseEntity<String>> asyncCallable() {
        return () -> {
            // 模拟耗时操作
            Thread.sleep(3000);
            return ResponseEntity.ok("异步响应(Callable)");
        };
    }
    
    // 异步请求(返回CompletableFuture)
    @GetMapping("/future")
    public CompletableFuture<ResponseEntity<String>> asyncFuture() {
        return asyncService.doAsyncTask();
    }
}

// 异步服务
@Service
public class AsyncService {
    
    @Async // 异步方法
    public CompletableFuture<ResponseEntity<String>> doAsyncTask() {
        try {
            Thread.sleep(3000);
            return CompletableFuture.completedFuture(ResponseEntity.ok("异步响应(CompletableFuture)"));
        } catch (InterruptedException e) {
            return CompletableFuture.failedFuture(e);
        }
    }
}

// 启用异步
@SpringBootApplication
@EnableAsync // 开启异步支持
public class SpringBootDemoApplication {
    // 自定义线程池(可选)
    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(20);
        executor.setThreadNamePrefix("async-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

5.4 打包与部署

5.4.1 打包为JAR包

bash# 复制代码
mvn clean package -DskipTests
# 运行JAR包
java -jar target/spring-boot-demo-1.0.0.jar
# 指定配置文件运行
java -jar target/spring-boot-demo-1.0.0.jar --spring.config.location=file:/opt/config/application.yml
# 指定端口运行
java -jar target/spring-boot-demo-1.0.0.jar --server.port=8081

5.4.2 打包为WAR包

  1. 修改pom.xml:
xml 复制代码
<!-- 1. 打包类型改为war -->
<packaging>war</packaging>

<!-- 2. 排除嵌入式Tomcat(由外部容器提供) -->
<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>

<!-- 3. 添加Tomcat依赖(提供编译时依赖) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>
  1. 修改启动类:
java 复制代码
@SpringBootApplication
public class SpringBootDemoApplication extends SpringBootServletInitializer {
    
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(SpringBootDemoApplication.class);
    }
    
    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemoApplication.class, args);
    }
}
  1. 打包并部署到外部Tomcat:
bash 复制代码
mvn clean package -DskipTests# 将target下的WAR包复制到Tomcat的webapps目录,启动Tomcat即可

六、Spring Boot 常见问题

6.1 基础概念类

  1. Spring Boot 的核心注解是什么?各部分作用?

    • @SpringBootApplication:核心注解,整合@SpringBootConfiguration(配置类)、@EnableAutoConfiguration(自动配置)、@ComponentScan(组件扫描);
    • @EnableAutoConfiguration:开启自动配置,通过AutoConfigurationImportSelector加载自动配置类。
  2. Spring Boot 自动配置原理?

    • 核心:@EnableAutoConfigurationAutoConfigurationImportSelector → 加载META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports中的自动配置类 → 通过@Conditional注解判断是否生效 → 注册默认Bean(可通过@ConditionalOnMissingBean自定义覆盖)。
  3. Spring Boot 与 Spring MVC 的关系?

    • Spring Boot是开发脚手架,Spring MVC是Web开发框架;
    • 引入spring-boot-starter-web后,Spring Boot通过WebMvcAutoConfiguration自动配置Spring MVC核心组件(DispatcherServlet、HandlerMapping、HandlerAdapter等);
    • 开发者可通过WebMvcConfigurer扩展Spring MVC配置,或通过@EnableWebMvc完全自定义。

6.2 实战问题类

  1. 如何自定义Spring Boot的自动配置?

    • 步骤:
      1. 编写自动配置类(@Configuration + @Conditional系列注解);
      2. 编写配置属性绑定类(@ConfigurationProperties);
      3. META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports中配置自动配置类全限定名;
      4. 打包为starter,引入即可自动生效。
  2. Spring Boot 如何实现多环境配置?

    • 方式1:通过spring.profiles.active激活指定环境(如spring.profiles.active=prod);
    • 方式2:通过命令行参数激活(java -jar app.jar --spring.profiles.active=test);
    • 方式3:通过系统环境变量激活(SPRING_PROFILES_ACTIVE=dev)。
  3. Spring Boot 启动失败,端口被占用如何解决?

    • 方式1:修改端口(server.port=8081);
    • 方式2:查找并杀死占用端口的进程(netstat -ano | findstr 8080taskkill /F /PID 进程ID);
    • 方式3:配置端口随机(server.port=0)。

6.3 性能优化类

  1. Spring Boot 应用性能优化要点?
    • 容器优化:调整Tomcat线程池(server.tomcat.max-threads)、连接超时时间;
    • JVM优化:设置JVM参数(-Xms512m -Xmx1024m);
    • 依赖优化:移除无用starter,减少依赖体积;
    • 配置优化:关闭不必要的自动配置,启用缓存(如Thymeleaf缓存);
    • 代码优化:使用异步处理(@Async)、减少拦截器耗时逻辑。

七、总结

核心关键点

  1. 核心定位:Spring Boot是Spring生态的快速开发脚手架,核心理念是「约定优于配置」,通过自动配置和起步依赖简化开发;
  2. 自动配置
    • 核心触发点:@EnableAutoConfigurationAutoConfigurationImportSelector → 加载自动配置类;
    • 核心控制:@Conditional系列注解(如@ConditionalOnClass@ConditionalOnMissingBean)控制配置是否生效;
  3. 与Spring MVC整合
    • 引入spring-boot-starter-web自动配置Spring MVC核心组件;
    • 通过WebMvcConfigurer扩展MVC配置(拦截器、跨域、消息转换器);
    • 避免滥用@EnableWebMvc(会禁用自动配置);
  4. 最佳实践
    • 优先使用起步依赖,避免手动管理依赖版本;
    • 多环境配置通过spring.profiles.active激活;
    • 自定义配置优先使用@ConfigurationProperties绑定,而非@Value
    • 部署优先选择JAR包(内置容器),简化部署流程;
    • 应用监控引入spring-boot-starter-actuator,实时监控应用状态。
相关推荐
黎雁·泠崖2 小时前
Java静态方法:用法+工具类设计+ArrayUtil实战
java·开发语言
Sanyhem2 小时前
2025 年高频考点与深度追问点
java·面试
摇滚侠2 小时前
解决 IntelliJ IDEA 中 Maven 管理界面不是层级结构的问题
java·maven·intellij-idea
Leinwin2 小时前
Azure 存储重磅发布系列创新 以 AI 与云原生能力解锁数据未来
后端·python·flask
Mr Aokey2 小时前
RabbitMQ进阶实战:三种典型消息路由模式详解(订阅/路由/主题)
java·网络·rabbitmq
世界尽头与你2 小时前
Flask开启Debug模式
后端·网络安全·渗透测试·flask
无心水2 小时前
4、Go语言程序实体详解:变量声明与常量应用【初学者指南】
java·服务器·开发语言·人工智能·python·golang·go
sheji34162 小时前
【开题答辩全过程】以 食堂兼职管理系统为例,包含答辩的问题和答案
java·eclipse
0x532 小时前
JAVA|智能仿真并发项目-并行与并发
java·开发语言