俗话说,尺有所短,寸有所长,相较于在机器学习与科学计算领域独领风骚的 Python,Java 更专注于后端开发,深耕之下占据了半壁江山,这背后离不开语言的优势与框架的支持;
掌握 Java Web 框架,最自然的方式还是一步一个脚印,沿着技术发展的里程碑说起;涉及框架代码的地方,也去繁归简,采用仿写代码的方式来模拟框架运行机制;
1. 前置知识
1.1 反射
一般情况下关于Class Member的调用必须通过其对象实例或类(静态方法),反射另辟蹊径,让开发人员可以通过代码访问其成员,提供 Java 对象各种粒度的表示;
1.2 注解
注解类似接口 Interface, 主要起标识与参数传递的作用,与业务逻辑解耦;
它可被元注解 DIRT 注解,示例中的 DemoAnnotation 由 Target 注解来表明它适用于方法类型;
2.Socket与Servlet
2.1 Socket
Web 应用自然离不开底层网络的支持,其中网络数据的传输主要有两部分:套接字Socket与网络协议栈(操作系统实现),其中技术栈的复杂度交由计算机网络负责处理;
Java通过Socket API来提供网络编程支持,作为开发人员,主要与Socket打交道,一对连接由套接字对表示,套接字标识符为二元组:(端口,地址);
一个简单的 dummy server可通过如下代码完成:
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
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 传入
其中 application.properties 简单设置包扫描的路径
scanPackage=learn.web.springmvc.controller
3.2 初始化
- 1.Tomcat 加载 DispatcherServlet 时调用其 init 方法,开始根据传入的参数 init-param 及配置文件的路径加载配置;
- 2.进行包扫描,通过包名与文件名拼接得类的全路径名,放入类名列表中
- 3.通过反射机制,进行实例化
- 4.处理注解,初始化 HandlerMapping,先判断类是否有 Controller 注解,再判断方法是否有 RequestMapping 注解,拼接 URL 后注册配置项
3.3 请求分发
- 根据 handlerMapping 配置处理请求
2.参数解析 retrieveParams 负责进行参数的解析与对应赋值(请求参数与方法参数的映射),主要通过反射机制进行,这边简单通过Type进行匹配;