手写Spring MVC
闲及无聊 又打开了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" />在其中增加如此字段即可
效果如下
手写Spring MVC的更多相关文章
- 【Spring】手写Spring MVC
Spring MVC原理 Spring的MVC框架主要由DispatcherServlet.处理器映射.处理器(控制器).视图解析器.视图组成. 完整的Spring MVC处理 流程如下: Sprin ...
- 一个老程序员是如何手写Spring MVC的
人见人爱的Spring已然不仅仅只是一个框架了.如今,Spring已然成为了一个生态.但深入了解Spring的却寥寥无几.这里,我带大家一起来看看,我是如何手写Spring的.我将结合对Spring十 ...
- 手写Spring MVC框架(二) 实现访问拦截功能
前言 在上一篇文章中,我们手写了一个简单的mvc框架,今天我们要实现的功能点是:在Spring MVC框架基础上实现访问拦截功能. 先梳理一下需要实现的功能点: 搭建好Spring MVC基本框架: ...
- 手写Spring MVC框架(一) 实现简易版mvc框架
前言 前面几篇文章中,我们讲解了Spring MVC执⾏的⼤致原理及关键组件的源码解析,今天,我们来模仿它⼿写⾃⼰的mvc框架. 先梳理一下需要实现的功能点: tomcat加载配置文件web.xml: ...
- 手写 Spring
手写 Spring 不多说,简历装 X 必备.不过练好还是需要求一定的思维能力. 一.整体思路 思路要熟练背下来 1)配置阶段 配置 web.xml: XDispatchServlet 设定 init ...
- Spring学习之——手写Spring源码V2.0(实现IOC、D、MVC、AOP)
前言 在上一篇<Spring学习之——手写Spring源码(V1.0)>中,我实现了一个Mini版本的Spring框架,在这几天,博主又看了不少关于Spring源码解析的视频,受益匪浅,也 ...
- 我是这样手写 Spring 的(麻雀虽小五脏俱全)
人见人爱的 Spring 已然不仅仅只是一个框架了.如今,Spring 已然成为了一个生态.但深入了解 Spring 的却寥寥无几.这里,我带大家一起来看看,我是如何手写 Spring 的.我将结合对 ...
- 手写Spring框架,加深对Spring工作机制的理解!
在我们的日常工作中,经常会用到Spring.Spring Boot.Spring Cloud.Struts.Mybatis.Hibernate等开源框架,有了这些框架的诞生,平时的开发工作量也是变得越 ...
- 手写Spring+demo+思路
我在学习Spring的时候,感觉Spring是很难的,通过学习后,发现Spring没有那么难,只有你去学习了,你才会发现,你才会进步 1.手写Spring思路: 分为配置.初始化.运行三个阶段如下图 ...
随机推荐
- noi.ac #546 分组
题目链接:戳我 题目描述 现在有n个字符串,你需要从中选出一些字符串,使得选出的字符串能被分组,满足每组大小为2,且可以从每组选出该组的两个字符串的一个非空公共后缀,使得每组选出的串互不相同. 输入格 ...
- Linux下SHA256校验
一.将Hash: SHA256文件和需要检验的文件放在同一个文件夹内 二.$sha256sum -c SHA265 文件 输出: 校验文件:ok
- Vue_(基础)Vue中的指令
Vue.js中文文档 传送门 Vue的指令:其实就是单个JavaScript表达式,一般来说是带有v-前缀 Vue指令: v-model:数据双向绑定: v-text:以纯文本方式显示数据: v- ...
- 2015ACM/ICPC亚洲区沈阳站 部分题解
链接在这:http://bak.vjudge.net/contest/132442#overview. A题,给出a,b和n,初始的集合中有a和b,每次都可以从集合中选择不同的两个,相加或者相减,得到 ...
- git commit 合并到指定分支
1. 将指定的commit合并到当前分支 git cherry-pick commit_id 2. 合并多个连续 commit 到指定分支 假设需要合并 devlop 上从 fb407a3f 到 9 ...
- TCP输入 之 快速路径和慢速路径
概述 快速路径:用于处理预期的,理想情况下的数据段,在这种情况下,不会对一些边缘情形进行检测,进而达到快速处理的目的: 慢速路径:用于处理那些非预期的,非理想情况下的数据段,即不满足快速路径的情况下数 ...
- 【Java笔试】OYO校招Java工程师|牛客平台,算法:字符串翻转。附选择题解析
文章目录 1.Java笔试算法题:字符串翻转 2.单选题: 2.1.同一进程下的多个线程可以共享哪一种资源:data section 2.2.一个树形的叶结点在前序遍历和后序遍历下,可以相同的相对位置 ...
- vue——父组件调用子组件
<template> <div> child1 </div> </template> <script> export default { n ...
- vmvare ubuntu虚拟机固定ip设置
1.vmvare网络设置 2.window网络设置 3.ubuntu网络设置 先ifconfig 查看ip 已经设置为192.168.122.128 sudo vim /etc/network/int ...
- LC 967. Numbers With Same Consecutive Differences
Return all non-negative integers of length N such that the absolute difference between every two con ...