从 Socket 到 SpringMVC,探索Java Web 开发

427 阅读3分钟

俗话说,尺有所短,寸有所长,相较于在机器学习与科学计算领域独领风骚的 Python,Java 更专注于后端开发,深耕之下占据了半壁江山,这背后离不开语言的优势与框架的支持;

掌握 Java Web 框架,最自然的方式还是一步一个脚印,沿着技术发展的里程碑说起;涉及框架代码的地方,也去繁归简,采用仿写代码的方式来模拟框架运行机制;

1. 前置知识

1.1 反射

一般情况下关于Class Member的调用必须通过其对象实例或类(静态方法),反射另辟蹊径,让开发人员可以通过代码访问其成员,提供 Java 对象各种粒度的表示;

image-20210622142335320

image-20210622142335320

1.2 注解

注解类似接口 Interface, 主要起标识与参数传递的作用,与业务逻辑解耦;

它可被元注解 DIRT 注解,示例中的 DemoAnnotation 由 Target 注解来表明它适用于方法类型;

image-20210622142335320

2.Socket与Servlet

2.1 Socket

Web 应用自然离不开底层网络的支持,其中网络数据的传输主要有两部分:套接字Socket与网络协议栈(操作系统实现),其中技术栈的复杂度交由计算机网络负责处理;

image-20200624101157643

Java通过Socket API来提供网络编程支持,作为开发人员,主要与Socket打交道,一对连接由套接字对表示,套接字标识符为二元组:(端口,地址);

一个简单的 dummy server可通过如下代码完成:

image-20200624101157643

2.2 Servlet

Servlet 是 Java Web 开发的接口规范,在 Socket 基础上增加URL与Java类的映射**(url,servlet)​,类似于:\resource\list -> com.alan.XX**;

Servlet 除了实现 Servlet 接口之外并没有其它魔力,它无法独立地服务Web请求,必须要配合 Servlet 容器才能发挥它的真正作用,常见的 Servlet 容器有 Tomcat,Jetty等;

Servlet 容器负责 Servlet 的注册,加载,服务,可以通过配置加反射实现一个简单的 Servlet 容器,代码地址:XX;

  • 监听服务地址,获取网络连接,根据Http协议将其转换为 Request 与 Response

  • 查取配置:

    • 通过反射加载对应 Servlet 实现类,调用 service 方法
    • 如果未配置对应 url,返回404

image-20200624101157643

3.SpringMVC

SpringMVC 将 Servlet 规范中URL与Servlet的映射抽象为HandlerMapping ** (url,handler),在此基础上新增一层映射ViewResolver** (view,html_etc)

HandlerMapping 的映射中,结果为两类:

  • 匹配满足,交由对应的Handler处理

  • 匹配不满足

    • 若存在默认handler,走默认handler
    • 返回404

SpringMVC 基于 Spring 框架,通过注解的方式来简化Web开发,调度类为DispatchServlet,它注册至Servlet容器,负责拦截请求并进行分发;

3.1 配置

Tomcat 配置文件 web.xml 如下,设置预加载DispatchServlet,并将配置地址通过 init-param 传入

image-20200624101157643

其中 application.properties 简单设置包扫描的路径

scanPackage=learn.web.springmvc.controller

3.2 初始化

  • 1.Tomcat 加载 DispatcherServlet 时调用其 init 方法,开始根据传入的参数 init-param 及配置文件的路径加载配置;

image-20200624101157643

  • 2.进行包扫描,通过包名与文件名拼接得类的全路径名,放入类名列表中

image-20200624101157643

  • 3.通过反射机制,进行实例化
  • 4.处理注解,初始化 HandlerMapping,先判断类是否有 Controller 注解,再判断方法是否有 RequestMapping 注解,拼接 URL 后注册配置项

image-20200624101157643

3.3 请求分发

  • 根据 handlerMapping 配置处理请求

image-20200624101157643

2.参数解析 retrieveParams 负责进行参数的解析与对应赋值(请求参数与方法参数的映射),主要通过反射机制进行,这边简单通过Type进行匹配;

image-20200624101157643