Spring之手写MVC三大核心组件
Posted Huterox
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring之手写MVC三大核心组件相关的知识,希望对你有一定的参考价值。
文章目录
前言
本系列终于迎来了第二个核心功能的编写,首先我们Spring里面一共有三个比较重要的核心功能,首先自然是咱们的IOC反转控制DI依赖注入当然还有AOP切面。这一部分的话我们前面看《Spring5核心原理与30个类手写实战 》是已经熟悉,并且照猫画虎实现了一下的,不过我们此时还没有实现AOP部分,而今天的部分呢是MVC部分,实现咱们最核心的功能之一,当然也是最简单的model,后面还有对数据库的支持。那么基本上三个组件就差不多了,那么后面我再根据自己的理解去升级维护(仿造Spring的真实源码)。虽然我们整个系列,包括这本书其实更多地是偏向这个思想,而不是直接看源码,这样首先是我觉得会一头雾水,不知道为啥这样设计,那么自己先看看书,看看大佬的东西,就会对这个总体的思想有一个认识,然后自己去写,然后去想为什么这样写,然后后面结合实际的源码,知道还能怎样优化。
在这里先建议各位小伙伴先前查看前两篇博文。
Spring之手写SpringMVC5个注解
Spring之手写SpringMVC5个注解(之IOC,DI优化)了解三级缓存
坚持到最后文末获取仓库地址。
流程回顾(MVC)
在此之前我们先简单回顾一下最开始的那个版本对于MVC的处理流程,这个非常重要。
首先我们的MVC,其实有两个部分,一个是我们的初始化部分。初始化部分又是分为两个小部分,第一个小部分自然就是我们的IOC部分,第二个部分就是专属于我们MVC的部分。
之后是我们的分发器,这个是我们MVC的执行组件。
这个就是我们原来的执行流程,显然我们发现整个步骤还是可以优化的,并且我们还可以添加组件。
MVC 最重要的一点是啥,显然是我们的view和model呀,视图加载和数据渲染呀。
SpringMVC九大组件(了解)
在我们进入我们的内容之前,我们还是需要先简单了解一下我们SpringMVC的九大组件的。
initMultipartResolver(context) 多文件上传组件
initThemeResolver(context) 初始化模板处理器
//mvc mapping组件(扫描mvc注解参数)
initHandlerMappings(context);
// 参数适配器,匹配参数执行方法
initHandlerAdapters(context);
initHandleExceptionResolvers(context) 异常拦截器
initRequestToViewNameTranslator(context) 初始化视图预处理器
// 初始化视图转换器
initViewResolvers(context);
//FlashMap处理器
initFlashMapManager(context);
那么今天我们显然想要实现的是
initHandlerMappings(context);
initHandlerAdapters(context);
initViewResolvers(context);
新的流程
ok,回到我们这里,既然我们要说优化,那么显然我们需要实现这三个玩意,那么显然我们需要对现在的流程做一点处理。
初始化流程
这里的话我们主要讨论MVC部分的流程,至于IOC,DI的部分咱们就不关注了这里。对应的代码就是这里
组件初始化
初始化干了啥
刚刚看到这个你可能会比较懵逼,那么我门就来说说这三个类到底干了啥。
这里直接看到咱们的流程图
那么整个过程就是我们的初始化部分。
执行流程
之后就是咱们的执行过程
首先其前面两个都是老朋友了,主要是后面我们到底干了啥,也就是我们的视图解析部分,到底干了啥。
首先明确一点,我们的通过初始化已经把我们 的html文件和对应的名字都封装起来了,对应的就是我们的ModelandView
那么model里面是我们需要渲染的数据,这个部分我们接下来是需要通过我们的模板引擎去做的。
而解析这一切的是我们的入口
之后这个view会帮我们做的就是解析模板
而之所以会这样,其实重点的诀窍之一还是在我们的adapte里面
那么这个就是整个MVC的核心流程。
这里的重点其实就是我们几个被封装的“信息类”,就是那些封装信息的类。
“信息类”
HUHandlerMapping
首先自然就是我们的handlermapping 封装了,我们扫描到的其对应的方法和对应的url(这里是做了正则所以其实是模式)之后是它的controller。
HUModelAndView
这个封装的是视图(你可以理解为html)的名字和我们接下来需要交给解析器渲染的数据。
当然与之配套的是HUViewResolver
HUViewResolver 与 HUModelAndView 的关系
其实看名字就知道,前者其实是帮助我们加载 后者对应的html 文件和把要解析的数据给模板引擎的。
解析器 HUView
之后的重点是我们的解析器。这里的话是 HUView 这个类。
package com.huterox.spring.framework.webmvc.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HUView
private File viewFile;
public HUView(File templateFile)
this.viewFile = templateFile;
public void render(Map<String,?> model, HttpServletRequest req, HttpServletResponse resp) throws IOException
StringBuffer sb = new StringBuffer();//最后输出的内容
RandomAccessFile ra = new RandomAccessFile(this.viewFile,"r");
String line = null;
while (null!=(line=ra.readLine()))
line = new String(line.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
Pattern pattern = Pattern.compile("\\\\$\\\\[^\\\\]+\\\\",Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(line);
while (matcher.find())
String paramName = matcher.group();
paramName = paramName.replaceAll("\\\\$\\\\|\\\\", "");
Object paramValue = model.get(paramName);
line = matcher.replaceFirst(makeStringForRegExp(paramValue.toString()));
matcher = pattern.matcher(line);
sb.append(line);
resp.setCharacterEncoding("UTF-8");
resp.getWriter().write(sb.toString());
resp.getWriter().flush();
public static String makeStringForRegExp(String str)
//特殊字符转移
return str.replace("\\\\","\\\\\\\\").replace("*","\\\\*")
.replace("+","\\\\+").replace("|","\\\\|")
.replace("","\\\\").replace("","\\\\")
.replace("(","\\\\(").replace(")","\\\\)")
.replace("^","\\\\^").replace("$","\\\\$")
.replace("[","\\\\[").replace("]","\\\\]")
.replace("?","\\\\?").replace(",","\\\\,")
.replace(".","\\\\.").replace("&","\\\\&");
整个核心是我们的正则表达式
用它来渲染数据。
测试
ok 话不多少进入测试环节
数据渲染ok
项目获取
那么接下来就是获取咱们的项目了。这次的话我是直接上传gitee了,对是直接在gitee
https://gitee.com/Huterox/springcoding
以上是关于Spring之手写MVC三大核心组件的主要内容,如果未能解决你的问题,请参考以下文章
#yyds干货盘点#30个类手写Spring核心原理之AOP代码织入
#yyds干货盘点#30个类手写Spring核心原理之MVC映射功能
#yyds干货盘点# Spring核心原理分析之MVC九大组件