Spring生态启动过程

Spring 是一个庞大的技术生态,很难用一个"大图"描述清全部流程。下面我将 Spring 的核心模块拆解开来,为你逐一梳理它们的执行流程。

🌐 Spring MVC:处理 HTTP 请求的核心流程

Spring MVC 的核心是 DispatcherServlet(前端控制器) ,它负责接收请求并委派给相应的组件处理。整个流程大致可以分为 找路 → 适配 → 执行 → 返回 → 解析 → 渲染 → 响应 这几步。

为了更直观地理解,我们来看一个流程图:

这个流程图展示了 Spring MVC 处理一个请求的完整路径。下面我们结合步骤进一步拆解:

1. 找路阶段
  • 步骤1:接收请求 :客户端发起 HTTP 请求,Tomcat 接收后将其交给 DispatcherServlet

  • 步骤2:查找处理器DispatcherServlet 询问 HandlerMapping,寻找能处理该请求的 ControllerHandlerMapping 会通过 @RequestMapping 注解或配置等方式进行匹配,并返回 HandlerExecutionChain(处理器和拦截器列表)。

  • 步骤3:适配处理器DispatcherServlet 将找到的 Handler 交给 HandlerAdapterHandlerAdapter 负责适配不同类型的 Handler(如注解式 Controller、实现 Controller 接口的类等)。

2. 执行阶段
  • 步骤4:参数处理并执行业务RequestMappingHandlerAdapter(最常用的 HandlerAdapter)进行参数绑定、数据转换、数据校验等工作,然后通过反射调用 Controller 的目标方法,真正执行业务逻辑。
3. 响应阶段
  • 步骤5:返回 ModelAndViewController 方法执行完毕后,会返回 ModelAndView 对象(包含逻辑视图名称和模型数据),或者通过 @ResponseBody 直接返回数据(如 JSON)。

  • 步骤6:解析视图DispatcherServlet 根据 ModelAndView 中的逻辑视图名,请求 ViewResolver 将逻辑视图名解析为真正的 View 视图对象(如 JSP, Thymeleaf 等)。

  • 步骤7:渲染并响应DispatcherServlet 使用 View 对象进行视图渲染,最终将响应结果返回给客户端。

🚀 Spring Boot:从 main 方法到应用启动

一个 Spring Boot 应用的启动,核心就是 SpringApplication.run() 方法的执行,其流程大致如下:

具体来说,整个启动过程主要分这几个阶段:

  • 第一阶段:创建 SpringApplication 对象
    main 方法调用 SpringApplication.run,首先会创建一个 SpringApplication 实例。在它的构造方法中,会完成一些初始化工作:推断应用类型 (如是否为 Web 项目)、加载 ApplicationContextInitializerApplicationListener

  • 第二阶段:执行 run() 方法

    这是启动的核心,主要逻辑包括:

    1. 启动监听器 :创建 StopWatch 开始计时,并通过 SpringApplicationRunListeners 发布 ApplicationStartingEvent 事件,通知所有监听器应用已开始启动。

    2. 环境准备 :创建 ConfigurableEnvironment,加载系统属性、环境变量和应用配置文件(application.propertiesapplication.yml),并发布 ApplicationEnvironmentPreparedEvent

    3. 打印 Banner :打印 Spring Boot 的启动图案(可在 banner.txt 中自定义)。

    4. 创建上下文 :根据应用类型(如 Web 应用或非 Web 应用)创建对应的 ApplicationContext 实例。对于 Web 应用,通常是 AnnotationConfigServletWebServerApplicationContext

    5. 准备上下文 :将 Environment 等组件设置到上下文中,并执行所有 ApplicationContextInitializer,然后发布 ApplicationContextInitializedEvent

    6. 刷新上下文 :调用 context.refresh(),这是整个启动流程的核心,负责加载所有 BeanDefinition、执行 BeanFactoryPostProcessor、注册 BeanPostProcessor、创建单例 Bean 并启动内嵌的 Web 服务器(如 Tomcat)。

    7. 执行 Runners :在容器刷新完成后,执行所有实现了 ApplicationRunnerCommandLineRunner 接口的 Bean,用于执行一些初始化逻辑。

  • 第三阶段:启动完成

    最后,发布 ApplicationReadyEvent 事件,标志应用已经完全启动,可以对外提供服务。

📦 Spring IoC 容器:Bean 的生命周期

Spring IoC 容器的核心是管理 Bean 的生命周期,主要阶段包括 实例化 → 属性赋值 → 初始化 → 销毁

这里还有一些关键节点值得深入理解:

  • 加载配置 :Spring 容器通过 BeanDefinitionReader 读取 XML、注解或 Java 配置类,生成 BeanDefinition 元数据。

  • 实例化:通过反射创建 Bean 的实例。

  • 属性赋值(依赖注入) :根据 BeanDefinition 中的信息,通过 Setter 方法或构造器等方式进行依赖注入。

  • 初始化:Bean 完全创建后,会调用一系列初始化方法。

    • Aware 接口回调 :如果 Bean 实现了 BeanNameAwareBeanFactoryAwareApplicationContextAware 等接口,Spring 会调用其 setXXX 方法,让 Bean 获取容器中的特定资源。

    • BeanPostProcessor 前置处理 :在 Bean 的初始化方法执行前,会调用所有注册的 BeanPostProcessorpostProcessBeforeInitialization 方法。AOP 的代理就是在这里创建的。

    • 自定义初始化 :执行使用 @PostConstruct 注解的方法或实现 InitializingBean 接口的 afterPropertiesSet 方法。

    • BeanPostProcessor 后置处理 :在初始化方法执行后,会调用 postProcessAfterInitialization 方法。

  • 使用 :Bean 初始化完成后,会被存入单例池(singletonObjects)供应用程序使用。

  • 销毁 :当容器关闭时,会调用使用 @PreDestroy 注解的方法或实现 DisposableBean 接口的 destroy 方法。

🛡️ Spring Security:请求的安全过滤链

Spring Security 的核心是一个过滤器链,在请求到达 DispatcherServlet 之前进行安全拦截,其完整流程如下:

整个流程通常被划分为 认证授权 两个阶段:

  1. 认证阶段 (你是谁?)

    用户请求进来后,首先进入一系列安全过滤器(如 UsernamePasswordAuthenticationFilter)。过滤器会从请求中提取用户名和密码等信息,然后调用 AuthenticationManager 进行认证,而 AuthenticationManager 会使用 UserDetailsService 加载用户信息并比对密码。认证成功后,用户信息会被存入 SecurityContextHolder。如果认证失败,请求流程在此中断,并返回失败信息给客户端。

  2. 授权阶段 (你能做什么?)

    认证成功后,请求会进入授权相关过滤器(如 FilterSecurityInterceptor),它会根据请求的 URL 等信息,调用 AccessDecisionManager 进行授权决策。如果授权成功,请求会被转发给 Controller 执行业务逻辑;如果授权失败,则返回 AccessDeniedException 或 403 状态码。

📂 Spring Data JPA:简化数据库操作

Spring Data JPA 通过 动态代理规范命名 的方式,极大地简化了数据库访问。当调用 Repository 接口方法时,其流程如下:

  1. 获取代理对象 :应用程序调用 Repository 接口的方法时,实际调用的是由 Spring Data JPA 在运行时通过 JdkDynamicAopProxy 生成的动态代理对象。

  2. 解析方法 :代理对象会拦截方法调用,根据方法命名规范 (如 findByLastName)解析出查询意图,或者识别出是自定义的 @Query 查询。

  3. 创建查询PartTreeJpaQuery 会根据解析出的查询条件,生成相应的 JPA Query 对象。

  4. 委托给 JPA 实现 :最终,SimpleJpaRepository 封装了标准的 JPA 操作,它会调用底层的 JPA 实现(如 Hibernate)来执行实际的数据库操作。

✂️ Spring AOP:横切逻辑的织入

Spring AOP 的核心是 在 Bean 的生命周期中,通过动态代理,在目标方法执行时织入切面逻辑。其触发和执行的流程如下:

  1. 代理创建(发生在 Bean 的初始化阶段)

    当一个 Bean 被实例化并完成依赖注入后,在初始化阶段 ,Spring AOP 会通过 BeanPostProcessor 的后置处理方法 postProcessAfterInitialization 来检查该 Bean 是否匹配某个切点(Pointcut)。如果匹配,Spring 就会为该 Bean 创建一个代理对象(JDK 动态代理或 CGLIB 代理),而不是直接返回原始 Bean 对象。

  2. 方法调用与拦截器链

    当从容器中获取到代理对象,并调用其目标方法时,代理对象会拦截调用,并执行一条 "拦截器链(MethodInterceptor Chain)" 。这条链的顺序遵循"后进先出"的栈式调用结构,执行顺序取决于切入类型(AspectJ 风格下,@Around > @Before > @After > @AfterReturning / @AfterThrowing)。

🗄️ Spring 事务管理:声明式事务的实现原理

Spring 声明式事务(@Transactional)的实现,本质上也是建立在 AOP 的基石之上的。流程是这样的:

  1. 代理对象 :当一个 Bean 带有 @Transactional 注解时,Spring 会为其创建一个代理对象。

  2. 事务增强 :当调用代理对象中的方法时,TransactionInterceptor(事务拦截器)会在目标方法执行前,根据 @Transactional 注解配置的事务传播行为(Propagation)等属性,通过 PlatformTransactionManager 获取并开启一个事务。

  3. 方法执行:目标方法执行。

  4. 提交或回滚TransactionInterceptor 会根据目标方法的执行结果来决定事务的提交或回滚。如果方法正常执行完毕,则提交事务;如果方法抛出未捕获的异常且符合事务回滚规则(默认是 RuntimeExceptionError),则回滚事务。

☁️ Spring Cloud 微服务:一个请求的流转路径

在微服务架构中,一个外部请求的处理流程通常如下:

  • 请求进入 :请求首先到达 API 网关(如 Spring Cloud Gateway),它是所有外部请求的统一入口。

  • 认证鉴权 :网关将请求转发到 认证中心 进行身份认证和权限校验。

  • 服务发现 :认证通过后,网关会向 服务注册中心(如 Nacos、Eureka)查询目标服务(如"业务微服务A")的可用实例地址列表。

  • 路由与调用 :网关通过负载均衡组件(如 Ribbon)选择一个服务实例,将请求路由过去。

  • 业务处理 :"业务微服务A"处理请求。处理过程中,如果需要调用"业务微服务B",则会通过 Feign 等声明式 HTTP 客户端发起调用。

  • 结果返回:调用结果沿着调用链原路返回,最终由网关响应给客户端。

💎 总结

  • Spring MVC 的请求处理是围绕 DispatcherServlet找路 → 适配 → 执行 → 返回 → 解析 → 渲染 → 响应 九步曲。

  • Spring Boot 的启动是从 main 方法开始,创建 SpringApplication 并执行 run 方法,最终创建并刷新 IoC 容器、启动内嵌 Web 服务器。

  • Spring IoC 的核心是 Bean 的完整生命周期管理 ,并通过 BeanPostProcessorBeanFactoryPostProcessor 提供扩展点。

  • Spring Security 通过一系列 安全过滤器链 ,在请求到达 Controller 前完成 认证和授权 两个核心阶段。

  • Spring AOP 通过 动态代理 织入切面逻辑,Spring 声明式 事务 正是其核心应用。

  • Spring Data JPA 通过 动态代理方法命名规范,简化了数据访问。

  • Spring Cloud 微服务架构中,外部请求一般通过 API 网关 路由,结合 服务注册与发现负载均衡 等组件完成跨服务的调用。

相关推荐
invicinble13 小时前
对于spring的bean应该有哪些领域的认识
java·后端·spring
用户3983461612013 小时前
Go-Spring 实战第 11 课 —— 依赖注入的目标:单 Bean 注入和集合注入
spring·go
梵得儿SHI13 小时前
SpringCloud 进阶拓展:Spring Security OAuth2+JWT 微服务统一认证授权全实战|生产级方案 + 源码解析 + 踩坑实录
spring·spring cloud·微服务·spring security·jwt·oauth2·统一认证授权
JAVA面经实录91714 小时前
完整版Spring全家桶学习体系
java·spring boot·spring·面试
架构源启15 小时前
Spring AI进阶系列(09) 工作流引擎设计:LangGraph风格编排、条件分支与并行执行实战
java·人工智能·spring
_Aaron___15 小时前
Spring AI 2.0 之后,MCP Server 该按远程企业服务来设计
java·人工智能·spring
多加点辣也没关系16 小时前
Spring MessageSource 国际化方案
java·后端·spring
java1234_小锋1 天前
Spring AI 2.0 开发Java Agent智能体 - MCP(模型上下文协议)
java·人工智能·spring·spring ai
辰海Coding1 天前
MiniSpring框架学习-整合 IoC 和 MVC(NPC)
学习·spring·mvc