手把手带你写一个 MiniSpring
郭屹
前 Sun Microsystems Java 研发工程师,开源软件 MiniSpring、MiniTomcat 开发者
6170 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 26 讲
手把手带你写一个 MiniSpring
15
15
1.0x
00:00/00:00
登录|注册

07|原始MVC:如何通过单一的Servlet拦截请求分派任务?

你好,我是郭屹。从这节课开始,我们开启一个新的部分:MVC。
前面一章,我们实现了一个简单的 IoC。麻雀虽小,五脏俱全,相比原生 Spring 框架而言,我们写的 MiniSpring 功能简单,但其核心功能已具备。我们会在这个基础上进一步扩展我们的框架。
这一章我们来实现 Spring MVC。MVC,全名对应 Model(模型)、View(视图)、Controller(控制器)。它的基本流程是:前端发送请求到控制器,控制器寻找对应模型,找到模型后返回结果,渲染视图返回给前端生成页面。这是标准的前端请求数据的模型。实现了 MVC 之后,我们会把 MVC 和之前我们已经实现的 IoC 结合起来,这是我们这一章的整体思路。
这节课我们就开启 Spring MVC 的第一步,先实现一个原始的 MVC。目标是通过一个 Controller 来拦截用户请求,找到相应的处理类进行逻辑处理,然后将处理的结果发送给客户端。

调整目录

按照惯例,我们还是参照 Spring 的目录结构来调整。MVC 是 Web 模型,所以我们先调整一下目前的项目结构,采用 Web 的项目结构。同时,我们还要引入 Tomcat 服务器以及 Tomcat 的 jar 包。
你可以看一下项目目录结构,主要是新增一个和 src 目录同级的 WebContent 目录,在这个目录里存储部分前端页面需要的静态资源,还有各项 XML 配置文件。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了如何构建一个简单的MVC框架,通过实现一个原始的MVC框架来帮助读者了解请求的分发和处理的基本原理和实现过程。文章首先调整了项目目录结构,引入了Web的项目结构和Tomcat服务器以及Tomcat的jar包。然后详细解释了minisMVC-servlet.xml和web.xml的配置内容,以及如何解析servlet.xml文件。接着重点关注了Servlet的核心概念和web.xml的配置,解读了几个标签的含义。随后,实现了MVC的核心启动类DispatcherServlet,完成了URL映射机制。接着介绍了如何简化配置,引入@RequestMapping和实现ComponentScan,简化配置工作。最后,通过一个简单的测试类展示了DispatcherServlet的运行结果。整体来说,本文通过实例代码和详细解释,帮助读者了解了如何构建一个简单的MVC框架,实现了请求的分发和处理,展现了MVC框架的基本原理和实现过程。文章内容涵盖了MVC框架的搭建过程,以及如何简化配置和引入新的注解,为读者提供了一种更便捷的方式来构建和使用MVC框架。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《手把手带你写一个 MiniSpring》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(15)

  • 最新
  • 精选
  • 风轻扬
    思考题。我理解:MVC中的bean是为了标识这是一个controller,用来接收处理web层请求,而Spring中的bean感觉是一种服务能力,哪个地方需要这种能力,注入后就可以使用。不知道理解的对不对。 另外,跟代码的过程中,发现一个问题,如果包下有接口,Class.newInstance就会报错的。老师,将controller实例化处的代码是不是应该加个Class.isInstance()的判断呢?

    作者回复: 你的理解是对的。代码问题,MiniSpring是为了学习构建的,不是工业级的。线下听课的几波学生,要对照代码进行扩展练习,自己增加功能特性增加鲁棒性。

    2023-04-02归属地:北京
    4
    2
  • 零零后糖豆豆
    response设置contentType避免返回中文乱码 response.setContentType("text/html; charset=UTF-8");

    作者回复: 赞

    2023-05-12归属地:中国香港
    1
  • 云韵
    老师 文中的代码和下载的代码分支geek-mvc1 对应不上

    作者回复: 结果是对的上的。这一节中的开始的代码后面被重写了。你手工跟一遍最后就是一样的。不想跟的话,看文稿知道怎么演变过来的也可以。

    2023-03-29归属地:浙江
    1
  • x-arts
    源码给的过于随意了。。。。

    作者回复: 你看下Github上的,文稿中的开始部分的代码后面都重写过了,文稿是要展示演变的过程。minispring的目的是供理解框架的结构用的,便于以后读Spring框架源代码的时候理解。感谢你的指教。

    2023-03-28归属地:北京
    2
    1
  • 睿智的仓鼠
    加入注解后改造的initMapping()方法中 Class<?> clazz = this.controllerClasses.get(controllerName);下面缺少了一行: Object obj = this.controllerObjs.get(controllerName);

    作者回复: 感谢。文稿中排版有点问题。

    2023-03-27归属地:湖北
    1
  • Geek4329
    private List<String> scanPackage(String packageName) { List<String> tempControllerNames = new ArrayList<>(); URL url =this.getClass().getClassLoader().getResource("/"+packageName.replaceAll("\\.", "/")); File dir = new File(url.getFile()); for (File file : dir.listFiles()) { if(file.isDirectory()){ scanPackage(packageName+"."+file.getName()); }else{ String controllerName = packageName +"." +file.getName().replace(".class", ""); tempControllerNames.add(controllerName); } } return tempControllerNames; } 这个方法写的没问题么?照理说应该是递归把所有的类文件都加载进去,应该是tempControllerNames.addAll(scanPackage(packageName+"."+file.getName())) 是我理解有问题么?

    作者回复: 我就是用的递归啊

    2024-02-28归属地:北京
  • KernelStone
    搞了半天这节内容对我这种工程小白而言,难是难在从IDEA中进行项目部署。终于跑通了,参考链接如下: 1、https://blog.csdn.net/Wxy971122/article/details/123508532 2、https://blog.csdn.net/fannyoona/article/details/113933113 3、另外有需要可以搜一下Tomcat控制台乱码问题 还有感谢评论区的帮助!

    作者回复: 也感谢你的分享

    2023-06-03归属地:俄罗斯
  • Yangjing
    老师,扩展MVC前,启动 Tomcat,是要怎么配置 Tomcat、MiniS 配合启动的呢

    作者回复: 你要配web.xml,下载GitHub上的代码看看

    2023-04-09归属地:广东
    2
  • 睿智的仓鼠
    请问郭老师,最后DispatcherServlet中的controllerObjs和mappingObjs这两个map,存储的都是请求地址和处理请求的bean的映射关系,这里为什么要维护两份?我能理解它们的思想不同,但也想不出维护两份后期会有什么扩展。后期会体现出这样做的好处吗?

    作者回复: 不一样啊,一个是servletname另一个是URLMapping。

    2023-03-28归属地:湖北
  • Ben Guo
    关于启动Tomcat,可以加入 embeded tomcat的依赖,然后用下面的代码 跑起来 public class App { public static void main( String[] args ) throws LifecycleException { System.out.println( "Hello World!" ); Tomcat tomcat = new Tomcat(); String webappDirLocation = "WebContent"; StandardContext context = (StandardContext) tomcat.addWebapp("/", new File(webappDirLocation).getAbsolutePath()); Connector connector = new Connector(); connector.setPort(8080); tomcat.setConnector(connector); tomcat.start(); tomcat.getServer().await(); } }
    2023-07-11归属地:广东
    1
    2
收起评论
显示
设置
留言
15
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部