java 请求过程解读[一]
# 1. 引言与问题概述 🎯
# 1.1 背景介绍
在我们之前的分析中,我们探讨了一个完整请求的 demo,从前端发起请求,到后端处理,最终返回响应。在这篇文章中,我们将进一步深入源码,剖析 Ambari 如何通过封装和面向对象的设计理念来处理请求。Ambari 作为一个集群管理工具,面临的请求类型复杂且多样,而其核心请求处理机制是如何通过对象的结构来完成的,是我们本节探讨的重点。
提示
Ambari 的请求处理是基于 控制器(Controller)和 资源提供者(Provider)两大关键概念来组织的。每个请求都通过控制器处理,并通过对应的资源提供者来获取实际的数据或服务。
这一过程在源码层面是如何实现的?它如何使用面向对象的思想来封装请求的处理逻辑?
本文将深入源码,帮助你理解 Ambari 请求处理流程中的封装机制和如何通过面向对象的方式组织和管理这些复杂的服务间交互。通过解析 Ambari 如何将控制器、请求和资源提供者结合起来处理请求,我们将揭示 Ambari 中隐藏的强大功能。
# 1.2 本节目标
- 理解控制器与请求的关系:如何根据请求的路径和资源类型,快速定位到对应的 控制器(service),理解其在处理请求时的职责和作用。
- 解析控制器与资源提供者的协作:控制器如何通过 资源提供者(provider)来实现数据处理和返回结果,及其协作原理。
- 面向对象的封装逻辑:通过源码分析,理解 Ambari 如何通过控制器找到最终处理请求的 provider handler ,并进一步分析这个过程如何简化了复杂的请求处理流程。
# 2. 核心概念解析 🧠
笔记
本文核心概念已经在 《requiredServices详解》中详细解读过,可以翻看,本文不再赘述。
# 3. 实操与代码解析 🔧
# 3.1 请求的思考
在处理 API 请求时,理解请求的组成和流程对于调试和开发是至关重要的。每一个请求都有其特定的目标和路径,因此,熟悉如何解析请求和理解其各个部分,能够帮助我们更有效地定位问题和优化代码。
在本例中,我们分析了一个典型的 API 请求,它请求了 Ambari 系统中有关 BIGTOP
堆栈版本的所有服务。通过解析请求内容,我们可以理解它是如何与后端服务交互的。
# 3.1.1 请求示例与解析
curl 'http://centos1:8080/api/v1/stacks/BIGTOP/versions/3.2.0/services?fields=StackServices/*,components/*,components/dependencies/Dependencies/scope,components/dependencies/Dependencies/service_name,components/dependencies/Dependencies/type,artifacts/Artifacts/artifact_name&_=1732686583126' \
-H 'Accept: application/json, text/javascript, */*; q=0.01' \
-H 'Accept-Language: zh-CN,zh;q=0.9' \
-H 'Connection: keep-alive' \
-H 'Content-Type: text/plain' \
-H 'Cookie: AMBARISESSIONID=node01xovhqi7a1a1qhtl09nz93i002.node0' \
-H 'Referer: http://centos1:8080/' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36' \
-H 'X-Requested-By: X-Requested-By' \
-H 'X-Requested-With: XMLHttpRequest' \
--compressed \
--insecure
2
3
4
5
6
7
8
9
10
11
12
- 请求路径:
http://centos1:8080/api/v1/stacks/BIGTOP/versions/3.2.0/services
表示客户端请求获取BIGTOP
堆栈版本3.2.0
下的所有服务信息。 - 查询参数:
fields
:指定要返回的字段,仅请求堆栈服务相关必要字段。_=1732686583126
:防缓存用时间戳。
- 请求头:维持会话(Cookie),指定响应格式(Accept: application/json)等。
# 3.1.2 查找控制器
要理解该请求如何在代码中被处理,需要查找 Ambari 后端的控制器。最常用的方法是通过路径正则定位。
IDE 搜索技巧:
打开搜索框(
Ctrl+Shift+R
或Cmd+Shift+R
)。启用正则表达式,输入如下正则定位控制器路径:
.*/versions/.*/services
1查找结果,快速定位到控制器方法:
最终定位到如下控制器方法:
@GET
标明 GET 请求@Path
显式指定路径模板handleRequest
统一分发处理
# 3.1.3 控制器解读
文件路径:
src/main/java/org/apache/ambari/server/api/services/StacksService.java
# 3.1.3.1 控制器目录结构
Ambari 控制器统一存放于 src/main/java/org/apache/ambari/server/api/services/
。
该目录结构清晰,便于开发与维护。
# 3.1.3.2 控制器命名规范
笔记
控制器命名统一为 XXXService
,直接对应业务领域。
控制器名 | 主要职责 |
---|---|
StacksService | 处理堆栈/服务相关请求 |
ClustersService | 处理集群相关 |
HostsService | 处理主机相关 |
这样开发者见名知意,便于定位与维护。
# 3.2 Service 解析
# 3.2.1 BaseService
解析
Ambari 所有服务类(如 StacksService
)都继承自 BaseService
,实现通用请求处理能力。
继承优势:复用通用逻辑(如统一的 handleRequest、请求分发),提升解耦性和开发效率。
关键方法:
handleRequest()
:所有 HTTP 请求的统一入口,判断类型并分发。getRequestFactory()
:工厂方法,实例化具体类型请求对象。
# 3.2.2 请求的创建与分发
请求处理的关键在于工厂创建与类型分发:
request = getRequestFactory().createRequest(headers, requestBody, uriInfo, requestType, resource);
createRequest()
根据requestType
决定是GetRequest
、PostRequest
还是其他类型。- 每种请求对象有独立处理逻辑,职责分明。
创建后,调用请求对象的核心处理方法:
result = request.process();
- 处理流程涵盖参数解析、业务处理、结果组装与返回。
# 3.2.3 请求的处理流程
提示
每种请求类型(如 GetRequest
、PostRequest
)的 process()
方法封装了独立的业务处理细节。
- GET 请求:解析参数,数据库查询,返回资源集合。
- POST 请求:解析数据,校验、处理、存储,返回操作结果。
处理步骤统一:
- 参数解析(header, body, uriInfo 等)
- 业务处理(查库、写库、操作等)
- 结果返回(封装为 Resource 或业务对象/错误对象)
通过将请求类型与处理逻辑解耦,Ambari 可以灵活扩展不同请求场景,增强可维护性和代码复用性。