手写Spring MVC

2019-09-30 06:46:49来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

闲及无聊 又打开了CSDN开始看一看有什么先进的可以学习的相关帖子,这时看到了一位大神写的简历装X必备,手写Spring MVC。

我想这个东西还是有一点意思的 就拜读了一下大佬的博客 通读了一遍相关代码 感觉和我想象中spring的运作流程基本相同  但是我脑海中基本上只有一个非常简单的基本概念 而这位大佬具象化了相关的代码内容 值得学习一番。

同样的我的博客里代码都是图片 需要膜拜学习原博的同志 可以参考

版权声明:本文为CSDN博主「肖朋伟」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_40147863/article/details/96505433(代码可复制)

学习自《Spring 5核心原理与30个类手写实战》作者 Tom 老师

全文核心!!!!!!看明白了 才能真的学会如何去写 本文代码基本照搬肖老师的代码 在其中增加了一些自己学习的理解和心得

一、整体思路
思路要熟练背下来

1)配置阶段

配置 web.xml:
<sevlet>
XDispatchServlet          //继承HttpServlet类 重写doGet doPost init三个函数 在web.xml中配置的原因为保证在tomcat启动的时候对此类进行初始化 保证初始化的完成

设定 init-param: contextConfigLocation = applicationContext.properties          // 在类加载时 将配置文件初始化到 servlet的配置对象中 方便获取其中启动参数
<servlet-mapping>
设定 url-pattern: /*     // 表示此servlet接受并处理一切借口
配置 Annotation: @XController @XService @XAutowired @XRequestMapping      // 自定义注解类 从代码实现上来看 是类别的表示 方便Spring在通过反射方式加载相关对象时 能够更准确的对需要加载的对象进行分类 而不需要每个类进行逐条审查
2)初始化阶段

IOC:
调用 init() 方法: 加载配置文件
IOC 容器初始化: Map<String, Object>
扫描相关的类: scan-package=“com.xiaopengwei”
创建实例化并保存到容器: 同过反射机制将类实例化放入 IOC 容器中

 

PS:ioc容器 控制反转 主要作用为在tomcat启动时 将配置扫描路径下的相关对象全部初始化到一个map对象中 在需要使用时可以将相关对象直接进行使用 不会说 到了使用的时候在对相关对象进行加载 且不会出现重复某一对象重复生成多个实例的场景

从某种程度上缓解了内存的压力 ioc容器 核心就是一个Map对象存储需要使用的bean对象 通过beanId或beanName来对应 在需要使用的地方进行调用 且ioc容器就是java设计模式中工厂模式的经典使用。


DI:
进行 DI 操作: 扫描 IOC 容器中的实例,给没有赋值的属性自动赋值

 

PS:DI 注入 Spring容器中提供 参数注入 构造器注入 自动注入等方式 而本文中展示的为注解类型的自动注入 但是从本质上来说集中注入方式都是一样的 即可以理解为 在程序启动时加载某种注入的规则 即通过反射的方式将什么对象 注入至另一个的对象中的某个值中

MVC:
初始化 HandlerMapping: 将一个 URL 和一个 Method 进行一对一的关联映射 Map<String, Method>

 

PS:本文中的MVC相关基本只是url及对应函数之间的一个映射关系 参数及post请求中json字符串转化为相应对象的功能并未实现  但其实参数绑定 其实就是简单的参数名映射 json与类对象之间的相互转换 只要熟悉json对象的构造方式及简单的反射方法即可实现 何况 相关json对象解析的相关插件也有很多 如果有时间可以看一次相关插件的源码 了解一下人家关于类对象及反射的理解 从中学习


3)运行阶段

调用 doGet() / doPost() 方法: Web 容器调用 doGet() / doPost() 方法,获得 request/response 对象
匹配 HandleMapping: 从 request 对象中获得用户输入的 url,找到其对应的 Method
反射调用 method.invoker(): 利用反射调用方法并返回结果
response.getWrite().write(): 将返回结果输出到浏览器

 

PS:web容器已经相当于设定了相对稳定的规则 重写了其中的doGet/doPost方法即在http相关处理过程中加入了自己想要的一些处理 及自己的解析规则(Restful风格接口 从某种程度上来说 就复杂于本文中 的解析规则)

PS::突然想到了一句题外话 正因为重写了doGet及doPost方法 才给了aop处理的空间  假设 我们在初始化时 解析配置文件 增加一个Map<Object(aop执行规则,在什么函数之前 或在什么函数之后执行), method(需要执行的方法)> 然后在get及post方法实际处理方法的前后加上一个 针对此map的判断 不就实现了aop面向切面的思想了吗!!!

 

二、代码

1、代码架构

 

 简单的区分了spring容器需要的简化的一些对象

 

2、pom.xml 

 

 junit为默认加载的 实际上 spring还是基于servlet相关处理的一个机制 只是在此机制上 大大的发展和简化了很多地方的代码开发及冗余

使我们java从业人员可以更好的 更简易的进行相关代码开发工作

 

3、web.xml

 

 手写Spring的核心 XDispatchServlet 在此类中完成相关对象的初始化及注入工作

 

4、application.propertis

 

 

见名知意 扫描路径 设计思路及扫描此路径像的相关对象 并初始化加载至ioc容器中

 

5、自定义注解类

 

自动注入注解

 

 controller注解

 

 url相应路径注解

 

 Service类注解

 

PS:本来想在此详细解析@Target@Retention@Documented@interface等元注解 但是在搜索学习是被一篇博客教育的服服帖帖 建议大家可以学习一下

https://www.cnblogs.com/gmq-sh/p/4798194.html

如果不愿去看的话在此简要说明一下

@Target主要为标记当前注解使用的地点 TYPE为类、METHOD为方法、FILED为参数

@Retention主要表示此注解标识的对象生命周期 RUNTIME标识运行时使用 基本就会一直加载在运行内存中

@Documented Documented注解表明这个注释是由 javadoc记录的,在默认情况下也有类似的记录工具。 如果一个类型声明被注释了文档化,它的注释成为公共API的一部分(这个说明感觉比网址中的说明好理解一下 但是说实话 还是不太清楚这个的意义 还有待学习 希望日后学到其他的知识时可以理解)

 

6、核心XDispatchServlet

 

 相关引用

 

 初始化常量

 

 重启doGet及doPost方法

 

 自定义请求处理器(理论上就可以在这个函数中增加aop相关操作)

 

 重写servlet初始化方法 保证在tomcat启动时相关对象的加载

 

 

 初始化相关对象打印

 

 url请求映射对象初始化

 

 自动化注入

 

ioc容器初始化

 

 扫描路径下的相关类对象 因牵扯到文件夹的搜索 所以采用递归方式层层搜索加载

 

 记载配置

 

 此处字母大小写变更方式很有意思 牵扯到char值存储的一个因素 char值存储任何中文或英文其实内部存储的可以理解为一个标识码,此处已经默认className的首字母必然为大写所以未经判断 这个在实际应用中应该避免 

如果对char值存储的字符码值有兴趣可以百度搜索Unicode字符列表 至于为什么是加32 因为unicode字符集采用的计算方式为16进制 具体对应码可以百度查询

 

PS:因代码编写习惯 所以其实图片应该从下向上看 其实更符合此类加载的一个顺序 但更建议敲出来 直接在init方法中点进去关联着看

7、controller类

 

 

此处主要是为了展现自动注入及url映射的一个处理

 

8、服务层接口类

 

 实现类

 

 

 此处模拟实现假设是真的返回了业务处理后应返回的相关返回

 

 三、代码运行

 

 

 

 这个SpringMocker是我的项目名称如果不做特殊处理的话需要在url中增加此字段,即doDispatch函数中解析忽略的contextPath字段

 

如果需要隐藏项目名称需要在tomcat的conf目录下找到server.xml配置文件的HOST标签

<Context path="" docBase="SpringMocker" />在其中增加如此字段即可

 

 效果如下

 

 


原文链接:https://www.cnblogs.com/tiantanglw/p/11574873.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:并发编程 深入分析Volatile的实现原理

下一篇:java 8 date time 简单样例