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扫描并加载自动配置类核心底层注解
@AutoConfigurationSpring 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 启动流程(核心步骤)

  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)
<!-- 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启动的核心阶段是ApplicationContextrefresh()方法,对于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实例

TomcatServletWebServerFactorygetWebServer()方法会创建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),当客户端发送请求时:

  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 激活多环境

# 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:123456

3.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/mappingsSpring 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加载配置的优先级(从高到低):

  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 异步控制器

@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包

  1. 修改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>
  1. 修改启动类:
@SpringBootApplicationpublicclassSpringBootDemoApplicationextendsSpringBootServletInitializer{@OverrideprotectedSpringApplicationBuilderconfigure(SpringApplicationBuilder application){return application.sources(SpringBootDemoApplication.class);}publicstaticvoidmain(String[] args){SpringApplication.run(SpringBootDemoApplication.class, args);}}
  1. 打包并部署到外部Tomcat:
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,实时监控应用状态。

Read more

模板编译期排序算法

1、非修改序列算法 这些算法不会改变它们所操作的容器中的元素。 1.1 find 和 find_if * find(begin, end, value):查找第一个等于 value 的元素,返回迭代器(未找到返回 end)。 * find_if(begin, end, predicate):查找第一个满足谓词的元素。 * find_end(begin, end, sub_begin, sub_end):查找子序列最后一次出现的位置。 vector<int> nums = {1, 3, 5, 7, 9}; // 查找值为5的元素 auto it = find(nums.begin(

By Ne0inhk
算法卷一:起行

算法卷一:起行

今天是学Python算法的第1天,第一卷:起行。 目录 题引 序言 章一:悟透韬略——概念 章二:洞晓玄机——特性 1.输入 2.输出 3.有穷性 4.确定性 5.可行性 章三:优胜劣汰——优化 章四:统一度量衡——时间复杂度 1.引入 2.定义 3.大O记法 4.时间复杂度分类 5.几条基本计算规则 6.计算 7.常见的时间复杂度 章五:如虎添翼——timeit模块 章六:实例:Python中列表类型不同操作的时间效率 章七:列表和字典操作的时间复杂度

By Ne0inhk
HDFS元数据深度解析:存储位置、持久化机制与一致性保障

HDFS元数据深度解析:存储位置、持久化机制与一致性保障

HDFS元数据深度解析:存储位置、持久化机制与一致性保障 * 引言 * 一、元数据概述:HDFS的"大脑" * 1.1 什么是元数据? * 1.2 元数据的存储形式 * 二、元数据的存储位置 * 2.1 存储路径配置 * 2.2 目录结构解析 * 三、元数据的持久化机制:FsImage与EditLog * 3.1 核心设计思想 * 3.2 工作原理流程图 * 3.3 写入流程详解 * 3.4 检查点机制:合并FsImage和EditLog * 触发条件 * 合并流程 * 3.5 启动恢复流程 * 四、元数据一致性的保障机制 * 4.1 多级一致性保障

By Ne0inhk