徐昊 · TDD 项目实战 70 讲
徐昊
Thoughtworks 中国区 CTO
18159 人已学习
新⼈⾸单¥98
登录后,你可以任选4讲全文学习
课程目录
已完结/共 88 讲
实战项目二|RESTful开发框架:依赖注入容器 (24讲)
实战项目三|RESTful Web Services (44讲)
徐昊 · TDD 项目实战 70 讲
15
15
1.0x
00:00/00:00
登录|注册

39|RESTful Web Services(3):明确架构愿景与调用栈顺序

你好,我是徐昊。今天我们继续使用 TDD 的方式实现 RESTful Web Services。
在上节课,我们通过 Spike 将 DI 容器引入了实现,代码如下:
static class ResourceServlet extends HttpServlet {
private final Context context;
private TestApplication application;
private Providers providers;
public ResourceServlet(TestApplication application, Providers providers) {
this.application = application;
this.providers = providers;
context = application.getContext();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Stream<Class<?>> rootResources = application.getClasses().stream().filter(c -> c.isAnnotationPresent(Path.class));
ResourceContext rc = application.createResourceContext(req, resp);
Object result = dispatch(req, rootResources, rc);
MessageBodyWriter<Object> writer = (MessageBodyWriter<Object>) providers.getMessageBodyWriter(result.getClass(), null, null, null);
writer.writeTo(result, null, null, null, null, null, resp.getOutputStream());
}
Object dispatch(HttpServletRequest req, Stream<Class<?>> rootResources, ResourceContext rc) {
try {
Class<?> rootClass = rootResources.findFirst().get();
Object rootResource = rc.initResource(context.get(ComponentRef.of(rootClass)).get());
Method method = Arrays.stream(rootClass.getMethods()).filter(m -> m.isAnnotationPresent(GET.class)).findFirst().get();
return method.invoke(rootResource);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
在这个 Spike 的基础上,我们可以进一步细化架构的愿景:

明确调用栈顺序

接下来需要稍微 Spike 一下的,就是 Resource Dispatcher 的部分:
00:00 / 00:00
    1.0x
    • 2.0x
    • 1.5x
    • 1.25x
    • 1.0x
    • 0.75x
    • 0.5x
    网页全屏
    全屏
    00:00
    根据 Spike 的结果,我们可以得到这部分的架构愿景和调用栈顺序:
    如上图所示,为大致的组件划分。
    ResourceServlet:以 Servlet 的形式作为入口,处理 Http 请求。
    Application:指明 RESTful 应用所需的所有组件,比如 Root Resource、Providers 等,也是对于框架提供的服务的访问入口。
    ResourceRouter:Http 请求派发算法的实现载体。
    Providers:三个扩展点,也就是 MessageBodyWriter,MessageBodyReader 以及 ExceptionMapper。
    明确了这些之后,就可以进入分解任务的环节了。但是,在这之前,我们要如何处理 Spike 代码呢?
    00:00 / 00:00
      1.0x
      • 2.0x
      • 1.5x
      • 1.25x
      • 1.0x
      • 0.75x
      • 0.5x
      网页全屏
      全屏
      00:00

      思考题

      在进入下节课之前,希望你能认真思考如下两个问题。
      在当前架构愿景下,我们要如何分解任务?
      关于架构愿景的学习,你有什么收获吗?
      确认放弃笔记?
      放弃后所记笔记将不保留。
      新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
      批量公开的笔记不会为你同步至部落
      公开
      同步至部落
      取消
      完成
      0/2000
      荧光笔
      直线
      曲线
      笔记
      复制
      AI
      • 深入了解
      • 翻译
        • 英语
        • 中文简体
        • 中文繁体
        • 法语
        • 德语
        • 日语
        • 韩语
        • 俄语
        • 西班牙语
        • 阿拉伯语
      • 解释
      • 总结

      本文介绍了徐昊在实现RESTful Web Services过程中使用TDD的方式,并通过Spike引入DI容器的实现。在上节课的基础上,进一步细化了架构的愿景,明确了调用栈顺序。通过Spike的结果,得到了Resource Dispatcher的部分的架构愿景和调用栈顺序。文章提出了两个思考题,分别是在当前架构愿景下如何分解任务以及关于架构愿景的学习收获。通过本文,读者可以了解到作者在实现RESTful Web Services过程中的具体实现方式和架构愿景的明确化,以及对于架构愿景的思考和学习收获。

      仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
      《徐昊 · TDD 项目实战 70 讲》
      新⼈⾸单¥98
      立即购买
      登录 后留言

      全部留言(2)

      • 最新
      • 精选
      • aoe
        留下代码 https://github.com/wyyl1/geektime-tdd-framework/tree/3

        编辑回复: 嘻嘻每节课都在等你的代码~

        2022-06-16
        1
      • 张铁林
        https://github.com/vfbiby/tdd-restful
        2022-06-18
        1
      收起评论
      显示
      设置
      留言
      2
      收藏
      沉浸
      阅读
      分享
      手机端
      快捷键
      回顶部