Spring Boot 深度解析
一、Spring Boot 核心定位
Spring Boot 是基于 Spring 框架的快速开发脚手架,核心目标是简化Spring应用的初始化搭建和开发过程,解决了传统Spring应用「配置繁琐、依赖管理复杂、部署麻烦」的痛点。
- 核心理念:约定优于配置(Convention Over Configuration),通过默认配置减少开发者的配置工作;
- 核心优势:
- 自动配置:根据引入的依赖自动配置Spring组件(如引入
spring-boot-starter-web自动配置Spring MVC); - 起步依赖:将常用依赖打包为
starter,一键引入即可使用(如spring-boot-starter-web包含Spring MVC、Tomcat、Jackson等); - 嵌入式容器:内置Tomcat/Jetty/Undertow,无需手动部署WAR包,可直接运行JAR包;
- 简化监控:通过
spring-boot-starter-actuator快速实现应用监控; - 无代码生成/无XML配置:纯Java配置,开箱即用;
- 自动配置:根据引入的依赖自动配置Spring组件(如引入
- 应用场景:所有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:启动类触发自动配置
// Spring Boot启动类核心代码@SpringBootApplicationpublicclassSpringBootDemoApplication{publicstaticvoidmain(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@interfaceSpringBootApplication{// 排除指定自动配置类Class<?>[]exclude()default{};// 排除指定自动配置类(通过类名)String[]excludeName()default{};// 组件扫描路径String[]scanBasePackages()default{};}步骤2:@EnableAutoConfiguration 核心逻辑
// @EnableAutoConfiguration注解源码@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage// 自动配置包扫描(默认扫描启动类所在包)@Import(AutoConfigurationImportSelector.class)// 导入自动配置选择器public@interfaceEnableAutoConfiguration{String ENABLED_OVERRIDE_PROPERTY ="spring.boot.enableautoconfiguration";Class<?>[]exclude()default{};String[]excludeName()default{};}// AutoConfigurationImportSelector核心方法:加载自动配置类@OverridepublicString[]selectImports(AnnotationMetadata annotationMetadata){if(!isEnabled(annotationMetadata)){return NO_IMPORTS;}// 1. 加载META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件AutoConfigurationEntry autoConfigurationEntry =getAutoConfigurationEntry(annotationMetadata);returnStringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}// 加载自动配置类的核心方法protectedAutoConfigurationEntrygetAutoConfigurationEntry(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);returnnewAutoConfigurationEntry(configurations, exclusions);}步骤3:自动配置类的加载与生效
- Spring Boot启动时,会扫描
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件(Spring Boot 2.7+),该文件包含所有自动配置类的全限定名; - 每个自动配置类(如
WebMvcAutoConfiguration)通过@Conditional系列注解判断是否生效,例如:
// 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)publicclassWebMvcAutoConfiguration{// 配置视图解析器(Thymeleaf/JSP)@Bean@ConditionalOnMissingBean// 自定义ViewResolver会覆盖默认配置publicInternalResourceViewResolverdefaultViewResolver(){InternalResourceViewResolver resolver =newInternalResourceViewResolver(); resolver.setPrefix(this.mvcProperties.getView().getPrefix()); resolver.setSuffix(this.mvcProperties.getView().getSuffix());return resolver;}// 配置RequestMappingHandlerMapping(Spring MVC核心组件)@Bean@ConditionalOnMissingBeanpublicRequestMappingHandlerMappingrequestMappingHandlerMapping(```){RequestMappingHandlerMapping mapping =createRequestMappingHandlerMapping();// 省略配置逻辑```return mapping;}// 配置RequestMappingHandlerAdapter@Bean@ConditionalOnMissingBeanpublicRequestMappingHandlerAdapterrequestMappingHandlerAdapter(```){// 省略配置逻辑```return adapter;}}2.3 Spring Boot 启动流程(核心步骤)
- 初始化SpringApplication:解析启动类、设置应用类型(Servlet/Reactive)、加载初始化器和监听器;
- 加载环境配置:读取application.yml/application.properties、命令行参数、系统属性等;
- 创建ApplicationContext:根据应用类型创建AnnotationConfigServletWebServerApplicationContext(Servlet应用);
- 刷新容器:
- 执行BeanFactoryPostProcessor;
- 注册BeanPostProcessor;
- 初始化MessageSource;
- 初始化事件多播器;
- 初始化嵌入式Servlet容器(Tomcat);
- 注册并初始化所有Bean;
- 启动嵌入式容器:启动Tomcat/Jetty,绑定端口;
- 执行启动后处理器:触发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)
<!-- 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
// 仅在Servlet环境且存在Tomcat类时生效@AutoConfiguration@ConditionalOnClass({Servlet.class,Tomcat.class,UpgradeProtocol.class})@ConditionalOnMissingBean(value =ServletWebServerFactory.class, search =SearchStrategy.CURRENT)publicclassTomcatServletWebServerFactoryAutoConfiguration{// 创建Tomcat容器工厂Bean(核心)@BeanpublicTomcatServletWebServerFactorytomcatServletWebServerFactory(ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers,ObjectProvider<TomcatContextCustomizer> contextCustomizers,ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers){TomcatServletWebServerFactory factory =newTomcatServletWebServerFactory();// 应用自定义配置(如端口、线程池等) 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启动的核心阶段是ApplicationContext的refresh()方法,对于Web应用(ServletWebServerApplicationContext),会在刷新过程中调用createWebServer()方法创建Tomcat容器。
核心源码:ServletWebServerApplicationContext
publicclassServletWebServerApplicationContextextendsGenericWebApplicationContextimplementsConfigurableWebServerApplicationContext{privatevolatileWebServer webServer;// 封装Tomcat实例的对象@OverrideprotectedvoidonRefresh(){super.onRefresh();try{// 核心方法:创建WebServer(即Tomcat容器)createWebServer();}catch(Throwable ex){thrownewApplicationContextException("Unable to start web server", ex);}}privatevoidcreateWebServer(){WebServer webServer =this.webServer;ServletContext servletContext =getServletContext();if(webServer ==null&& servletContext ==null){// 1. 获取步骤2中创建的TomcatServletWebServerFactoryServletWebServerFactory factory =getWebServerFactory();// 2. 工厂创建TomcatWebServer(核心)this.webServer = factory.getWebServer(getSelfInitializer());getBeanFactory().registerSingleton("webServerGracefulShutdown",newWebServerGracefulShutdownLifecycle(this.webServer));getBeanFactory().registerSingleton("webServerStartStop",newWebServerStartStopLifecycle(this,this.webServer));}elseif(servletContext !=null){try{getSelfInitializer().onStartup(servletContext);}catch(ServletException ex){thrownewApplicationContextException("Cannot initialize servlet context", ex);}}initPropertySources();}}关键说明:
onRefresh():ApplicationContext刷新时触发,是创建Web容器的核心时机;factory.getWebServer():调用TomcatServletWebServerFactory的方法创建TomcatWebServer(Tomcat容器实例)。
步骤4:TomcatWebServer初始化Tomcat实例
TomcatServletWebServerFactory的getWebServer()方法会创建Tomcat实例,配置连接器(Connector)、引擎(Engine)、主机(Host)、上下文(Context)等核心组件。
核心源码:TomcatServletWebServerFactory
publicclassTomcatServletWebServerFactoryextendsAbstractServletWebServerFactory{@OverridepublicWebServergetWebServer(ServletContextInitializer```initializers){// 1. 创建Tomcat核心实例org.apache.catalina.startup.Tomcat tomcat =neworg.apache.catalina.startup.Tomcat();// 2. 配置Tomcat临时目录File baseDir =(this.baseDirectory !=null)?this.baseDirectory :createTempDir("tomcat"); tomcat.setBaseDir(baseDir.getAbsolutePath());// 3. 创建连接器(Connector),绑定配置的端口(默认8080)Connector connector =newConnector(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实例)returnnewTomcatWebServer(tomcat,getPort()>=0,getShutdown());}}核心源码:TomcatWebServer(Tomcat实例封装)
publicclassTomcatWebServerimplementsWebServer{privatefinalorg.apache.catalina.startup.Tomcat tomcat;// 原生Tomcat实例privatefinalboolean autoStart;publicTomcatWebServer(org.apache.catalina.startup.Tomcat tomcat,boolean autoStart){this.tomcat = tomcat;this.autoStart = autoStart;initialize();// 初始化Tomcat}privatevoidinitialize()throwsWebServerException{synchronized(this.monitor){try{// 配置Tomcat引擎addInstanceIdToEngineName();// 启动Tomcat(核心)this.tomcat.start();// 等待Tomcat启动完成,确保连接器监听端口startDaemonAwaitThread();}catch(Exception ex){stopSilently();destroySilently();thrownewWebServerException("Unable to start embedded Tomcat", ex);}}}@Overridepublicvoidstart()throwsWebServerException{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
@AutoConfiguration@ConditionalOnWebApplication(type =Type.SERVLET)@ConditionalOnClass(DispatcherServlet.class)@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)publicclassDispatcherServletAutoConfiguration{// 注册DispatcherServlet Bean@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)publicDispatcherServletdispatcherServlet(DispatcherServletProperties properties){DispatcherServlet dispatcherServlet =newDispatcherServlet(); dispatcherServlet.setDispatchOptionsRequest(properties.isDispatchOptionsRequest()); dispatcherServlet.setDispatchTraceRequest(properties.isDispatchTraceRequest());// 省略其他配置```return dispatcherServlet;}// 将DispatcherServlet注册到Tomcat的ServletContext@BeanpublicDispatcherServletRegistrationBeandispatcherServletRegistrationBean(DispatcherServlet dispatcherServlet,WebMvcProperties webMvcProperties){DispatcherServletRegistrationBean registration =newDispatcherServletRegistrationBean( 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),当客户端发送请求时:
- Tomcat的连接器接收请求;
- 请求被转发到DispatcherServlet;
- DispatcherServlet按照Spring MVC的流程处理请求(匹配Controller、执行业务逻辑、返回响应);
- 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 激活多环境
# application.ymlspring:profiles:active: dev # 激活开发环境---spring:config:activate:on-profile: dev server:port:8080logging:level:root: DEBUG ---spring:config:activate:on-profile: prod server:port:80logging:level:root: INFO 3.2.3 配置绑定(@ConfigurationProperties)
// 绑定配置文件中的属性@Configuration@ConfigurationProperties(prefix ="app")publicclassAppProperties{privateString name;privateString version;privateDatabase database;// 静态内部类绑定嵌套属性publicstaticclassDatabase{privateString url;privateString username;privateString 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:1234563.3 嵌入式容器
3.3.1 默认容器(Tomcat)配置
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)
<!-- 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 核心依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>3.4.2 核心配置
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 核心依赖
<!-- 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 启动类
@SpringBootApplicationpublicclassSpringMvcBootApplication{publicstaticvoidmain(String[] args){SpringApplication.run(SpringMvcBootApplication.class, args);}}4.1.3 控制器(Spring MVC)
@RestController@RequestMapping("/user")publicclassUserController{@GetMapping("/{id}")publicResponseEntity<User>getUserById(@PathVariableLong id){User user =newUser(); user.setId(id); user.setName("Spring Boot + MVC"); user.setAge(20);returnResponseEntity.ok(user);}@PostMappingpublicResponseEntity<User>createUser(@RequestBodyUser user){ user.setId(100L);returnResponseEntity.status(HttpStatus.CREATED).body(user);}}// 实体类publicclassUser{privateLong id;privateString name;privateInteger age;// getter/setter/toString}4.1.4 配置文件(application.yml)
server:port:8080servlet:context-path: /demo # Spring MVC配置spring:mvc:servlet:load-on-startup:1# 立即加载DispatcherServletformat:date: yyyy-MM-dd HH:mm:ss# 日期格式化web:resources:static-locations: classpath:/static/,classpath:/public/# 静态资源路径4.2 自定义Spring MVC配置
4.2.1 扩展WebMvcConfigurer
@ConfigurationpublicclassWebMvcConfigimplementsWebMvcConfigurer{// 1. 自定义拦截器@BeanpublicLoginInterceptorloginInterceptor(){returnnewLoginInterceptor();}// 注册拦截器@OverridepublicvoidaddInterceptors(InterceptorRegistry registry){ registry.addInterceptor(loginInterceptor()).addPathPatterns("/api/**").excludePathPatterns("/api/login");}// 2. 自定义消息转换器(如FastJson替换Jackson)@OverridepublicvoidconfigureMessageConverters(List<HttpMessageConverter<?>> converters){// 移除默认Jackson转换器 converters.removeIf(converter -> converter instanceofMappingJackson2HttpMessageConverter);// 添加FastJson转换器FastJsonHttpMessageConverter fastJsonConverter =newFastJsonHttpMessageConverter();FastJsonConfig fastJsonConfig =newFastJsonConfig(); fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss"); fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteMapNullValue); fastJsonConverter.setFastJsonConfig(fastJsonConfig); converters.add(fastJsonConverter);}// 3. 自定义视图解析器(Thymeleaf)@BeanpublicThymeleafViewResolverthymeleafViewResolver(ITemplateResolver templateResolver){ThymeleafViewResolver resolver =newThymeleafViewResolver(); resolver.setTemplateResolver(templateResolver); resolver.setCharacterEncoding("UTF-8");return resolver;}// 4. 跨域配置@OverridepublicvoidaddCorsMappings(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注解(会禁用自动配置):
@Configuration@EnableWebMvc// 禁用Spring Boot的WebMvcAutoConfigurationpublicclassFullWebMvcConfigimplementsWebMvcConfigurer{// 需手动配置所有Spring MVC组件(HandlerMapping、HandlerAdapter等)}4.3 全局异常处理(Spring Boot + MVC)
@RestControllerAdvicepublicclassGlobalExceptionHandler{// 处理参数绑定异常@ExceptionHandler(MethodArgumentNotValidException.class)publicResponseEntity<ErrorResponse>handleValidException(MethodArgumentNotValidException e){String message = e.getBindingResult().getFieldError().getDefaultMessage();ErrorResponse error =newErrorResponse(400,"参数错误", message);returnResponseEntity.badRequest().body(error);}// 处理业务异常@ExceptionHandler(BusinessException.class)publicResponseEntity<ErrorResponse>handleBusinessException(BusinessException e){ErrorResponse error =newErrorResponse(e.getCode(),"业务异常", e.getMessage());returnResponseEntity.status(e.getCode()).body(error);}// 处理所有未捕获异常@ExceptionHandler(Exception.class)publicResponseEntity<ErrorResponse>handleException(Exception e){ log.error("系统异常", e);ErrorResponse error =newErrorResponse(500,"服务器内部错误","系统繁忙,请稍后重试");returnResponseEntity.status(500).body(error);}// 错误响应实体@Data@AllArgsConstructorpublicstaticclassErrorResponse{privateint code;privateString type;privateString message;}}五、Spring Boot 高级特性
5.1 外部化配置优先级
Spring Boot加载配置的优先级(从高到低):
- 命令行参数(如
java -jar app.jar --server.port=8081); - 系统环境变量;
- 应用外部的application-{profile}.yml;
- 应用内部的application-{profile}.yml;
- 应用外部的application.yml;
- 应用内部的application.yml;
- @PropertySource注解加载的配置;
- 默认配置(Spring Boot自动配置)。
5.2 自定义启动器Banner
- 在resources目录下创建
banner.txt文件; - 写入自定义Banner(可通过Banner生成工具生成):
____ _ _ _ _ _ | _ \ | | | | | | | | (_) | |_) | __ _| |_| |_| | ___ ___| |__ _ _ __ | _ < / _` | __| __| |/ _ \/ __| '_ \| | '_ \ | |_) | (_| | |_| |_| | __/\__ \ | | | | |_) | |____/ \__,_|\__|\__|_|\___||___/_| |_|_| .__/ | | |_| :: Spring Boot :: (3.2.0) 5.3 异步处理
5.3.1 异步控制器
@RestController@RequestMapping("/async")publicclassAsyncController{@AutowiredprivateAsyncService asyncService;// 异步请求(返回Callable)@GetMapping("/callable")publicCallable<ResponseEntity<String>>asyncCallable(){return()->{// 模拟耗时操作Thread.sleep(3000);returnResponseEntity.ok("异步响应(Callable)");};}// 异步请求(返回CompletableFuture)@GetMapping("/future")publicCompletableFuture<ResponseEntity<String>>asyncFuture(){return asyncService.doAsyncTask();}}// 异步服务@ServicepublicclassAsyncService{@Async// 异步方法publicCompletableFuture<ResponseEntity<String>>doAsyncTask(){try{Thread.sleep(3000);returnCompletableFuture.completedFuture(ResponseEntity.ok("异步响应(CompletableFuture)"));}catch(InterruptedException e){returnCompletableFuture.failedFuture(e);}}}// 启用异步@SpringBootApplication@EnableAsync// 开启异步支持publicclassSpringBootDemoApplication{// 自定义线程池(可选)@BeanpublicExecutortaskExecutor(){ThreadPoolTaskExecutor executor =newThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(20); executor.setThreadNamePrefix("async-"); executor.setRejectedExecutionHandler(newThreadPoolExecutor.CallerRunsPolicy()); executor.initialize();return executor;}}5.4 打包与部署
5.4.1 打包为JAR包
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包
- 修改pom.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>- 修改启动类:
@SpringBootApplicationpublicclassSpringBootDemoApplicationextendsSpringBootServletInitializer{@OverrideprotectedSpringApplicationBuilderconfigure(SpringApplicationBuilder application){return application.sources(SpringBootDemoApplication.class);}publicstaticvoidmain(String[] args){SpringApplication.run(SpringBootDemoApplication.class, args);}}- 打包并部署到外部Tomcat:
mvn clean package -DskipTests# 将target下的WAR包复制到Tomcat的webapps目录,启动Tomcat即可六、Spring Boot 常见问题
6.1 基础概念类
- Spring Boot 的核心注解是什么?各部分作用?
@SpringBootApplication:核心注解,整合@SpringBootConfiguration(配置类)、@EnableAutoConfiguration(自动配置)、@ComponentScan(组件扫描);@EnableAutoConfiguration:开启自动配置,通过AutoConfigurationImportSelector加载自动配置类。
- Spring Boot 自动配置原理?
- 核心:
@EnableAutoConfiguration→AutoConfigurationImportSelector→ 加载META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports中的自动配置类 → 通过@Conditional注解判断是否生效 → 注册默认Bean(可通过@ConditionalOnMissingBean自定义覆盖)。
- 核心:
- 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 实战问题类
- 如何自定义Spring Boot的自动配置?
- 步骤:
- 编写自动配置类(
@Configuration+@Conditional系列注解); - 编写配置属性绑定类(
@ConfigurationProperties); - 在
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports中配置自动配置类全限定名; - 打包为starter,引入即可自动生效。
- 编写自动配置类(
- 步骤:
- Spring Boot 如何实现多环境配置?
- 方式1:通过
spring.profiles.active激活指定环境(如spring.profiles.active=prod); - 方式2:通过命令行参数激活(
java -jar app.jar --spring.profiles.active=test); - 方式3:通过系统环境变量激活(
SPRING_PROFILES_ACTIVE=dev)。
- 方式1:通过
- Spring Boot 启动失败,端口被占用如何解决?
- 方式1:修改端口(
server.port=8081); - 方式2:查找并杀死占用端口的进程(
netstat -ano | findstr 8080→taskkill /F /PID 进程ID); - 方式3:配置端口随机(
server.port=0)。
- 方式1:修改端口(
6.3 性能优化类
- Spring Boot 应用性能优化要点?
- 容器优化:调整Tomcat线程池(
server.tomcat.max-threads)、连接超时时间; - JVM优化:设置JVM参数(
-Xms512m -Xmx1024m); - 依赖优化:移除无用starter,减少依赖体积;
- 配置优化:关闭不必要的自动配置,启用缓存(如Thymeleaf缓存);
- 代码优化:使用异步处理(
@Async)、减少拦截器耗时逻辑。
- 容器优化:调整Tomcat线程池(
七、总结
核心关键点
- 核心定位:Spring Boot是Spring生态的快速开发脚手架,核心理念是「约定优于配置」,通过自动配置和起步依赖简化开发;
- 自动配置:
- 核心触发点:
@EnableAutoConfiguration→AutoConfigurationImportSelector→ 加载自动配置类; - 核心控制:
@Conditional系列注解(如@ConditionalOnClass、@ConditionalOnMissingBean)控制配置是否生效;
- 核心触发点:
- 与Spring MVC整合:
- 引入
spring-boot-starter-web自动配置Spring MVC核心组件; - 通过
WebMvcConfigurer扩展MVC配置(拦截器、跨域、消息转换器); - 避免滥用
@EnableWebMvc(会禁用自动配置);
- 引入
- 最佳实践:
- 优先使用起步依赖,避免手动管理依赖版本;
- 多环境配置通过
spring.profiles.active激活; - 自定义配置优先使用
@ConfigurationProperties绑定,而非@Value; - 部署优先选择JAR包(内置容器),简化部署流程;
- 应用监控引入
spring-boot-starter-actuator,实时监控应用状态。