广告
返回顶部
首页 > 资讯 > 后端开发 > Python >手把手写Spring框架
  • 895
分享到

手把手写Spring框架

2024-04-02 19:04:59 895人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录初始化阶段运行阶段HandlerAdapter形参列表:编译后就能拿到值实参列表:要运行时才能拿到值最后反射总结:这部分目标是mvc! 主要完成3个重要组件: HandlerM

这部分目标是mvc

主要完成3个重要组件:

HandlerMapping:保存URL映射关系

HandlerAdapter:动态参数适配器

ViewResolvers:视图转换器,模板引擎

springMVC核心组件执行流程:

在这里插入图片描述

在这里插入图片描述

相对应的,用以下几个类来实现上述的功能:

在这里插入图片描述

初始化阶段

在DispatcherServlet这个类的init方法中,将mvc部分替换为initStrategies(context):

在这里插入图片描述

并且调用初始化三个组件的方法。

分别完善这几个方法:


private void initViewResolvers(PigApplicationContext context) {
        //模板引擎的根路径
        String tempateRoot = context.getConfig().getProperty("templateRoot");
        String templateRootPath = this.getClass().getClassLoader().getResource(tempateRoot).getFile();
        File templateRootDir = new File(templateRootPath);
        for (File file : templateRootDir.listFiles()) {
            this.viewResolvers.add(new PIGViewResolver(tempateRoot));
        }
    }
    private void initHandlerAdapters(PigApplicationContext context) {
        for (PIGHandlerMapping handlerMapping : handlerMappings) {
            this.handlerAdapters.put(handlerMapping,new PIGHandlerAdapter());
        }
    }
    private void initHandlerMappings(PigApplicationContext context) {
        if(context.getBeanDefinitionCount() == 0){ return; }
        String [] beanNames = context.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            Object instance = context.getBean(beanName);
            Class<?> clazz = instance.getClass();
            if(!clazz.isAnnotationPresent(PIGController.class)){ continue; }
            String baseUrl = "";
            if(clazz.isAnnotationPresent(PIGRequestMapping.class)){
                PIGRequestMapping requestMapping = clazz.getAnnotation(PIGRequestMapping.class);
                baseUrl = requestMapping.value();
            }
            //默认只获取public方法
            for (Method method : clazz.getMethods()) {
                if(!method.isAnnotationPresent(PIGRequestMapping.class)){continue;}
                PIGRequestMapping requestMapping = method.getAnnotation(PIGRequestMapping.class);
                //   //demo//query
                String regex = ("/" + baseUrl + "/" + requestMapping.value().replaceAll("\\*",".*")).replaceAll("/+","/");
                Pattern pattern = Pattern.compile(regex);
                handlerMappings.add(new PIGHandlerMapping(pattern,instance,method));
                System.out.println("Mapped " + regex + "," + method);
            }
        }
    }

全局变量:

private List<PIGHandlerMapping> handlerMappings = new ArrayList<PIGHandlerMapping>();

private Map<PIGHandlerMapping,PIGHandlerAdapter> handlerAdapters = new HashMap<PIGHandlerMapping, PIGHandlerAdapter>();

private List<PIGViewResolver> viewResolvers = new ArrayList<PIGViewResolver>();

HandlerMapping与HandlerAdapter是一一对应的关系。

运行阶段

整体思路:

在这里插入图片描述

getHandler就是通过请求拿到URI,并与handlerMappings中存好的模板进行匹配:


    private PIGHandlerMapping getHandler(httpservletRequest req) {
        String url = req.getRequestURI();
        String contextPath = req.getContextPath();
        url = url.replaceAll(contextPath,"").replaceAll("/+","/");
        for (PIGHandlerMapping handlerMapping : this.handlerMappings) {
            Matcher matcher = handlerMapping.getPattern().matcher(url);
            if(!matcher.matches()){continue;}
            return handlerMapping;
        }
        return null;
    }

HandlerAdapter

HandlerAdapter的handle方法负责反射调用具体方法。需要匹配参数,那么需要先保存好实参和形参列表。

形参列表:编译后就能拿到值


Map<String,Integer> paramIndexMapping = new HashMap<String, Integer>();
        //提取加了PIGRequestParam注解的参数的位置
        Annotation[][] pa = handler.getMethod().getParameterAnnotations();
        for (int i = 0; i < pa.length; i ++){
            for (Annotation a : pa[i]) {
                if(a instanceof PIGRequestParam){
                    String paramName = ((PIGRequestParam) a).value();
                    if(!"".equals(paramName.trim())){
                        paramIndexMapping.put(paramName,i);
                    }
                }
            }
        }
        //提取request和response的位置
        Class<?> [] paramTypes = handler.getMethod().getParameterTypes();
        for (int i = 0; i < paramTypes.length; i++) {
            Class<?> type = paramTypes[i];
            if(type == HttpServletRequest.class || type == HttpServletResponse.class){
                paramIndexMapping.put(type.getName(),i);
            }
        }

实参列表:要运行时才能拿到值


 Map<String,String[]> paramsMap = req.getParameterMap();
        //声明实参列表
        Object [] parameValues = new Object[paramTypes.length];
        for (Map.Entry<String,String[]> param : paramsMap.entrySet()) {
            String value = Arrays.toString(paramsMap.get(param.geTKEy()))
                    .replaceAll("\\[|\\]","")
                    .replaceAll("\\s","");
            if(!paramIndexMapping.containsKey(param.getKey())){continue;}
            int index = paramIndexMapping.get(param.getKey());
            parameValues[index] = caseStringVlaue(value,paramTypes[index]);
        }
        if(paramIndexMapping.containsKey(HttpServletRequest.class.getName())){
            int index = paramIndexMapping.get(HttpServletRequest.class.getName());
            parameValues[index] = req;
        }
        if(paramIndexMapping.containsKey(HttpServletResponse.class.getName())){
            int index = paramIndexMapping.get(HttpServletResponse.class.getName());
            parameValues[index] = resp;
        }

最后反射

在这里插入图片描述

总结:

在这里插入图片描述

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: 手把手写Spring框架

本文链接: https://www.lsjlt.com/news/133352.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 手把手写Spring框架
    目录初始化阶段运行阶段HandlerAdapter形参列表:编译后就能拿到值实参列表:要运行时才能拿到值最后反射总结:这部分目标是MVC! 主要完成3个重要组件: HandlerM...
    99+
    2022-11-12
  • 手把手Maven搭建SpringMVC+Spring+MyBatis框架(超级详细版)【转】
    一. 框架详情Spring 是一个轻量级的Java开发框架,它是为了解决企业应用开发的复杂性而创建的。Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应...
    99+
    2022-10-18
  • 手把手教你写Maven的archetype项目脚手架
    目录一、背景二、手写普通单模块项目的archetype三、手写maven多module的项目骨架archetype1.多模块骨架项目的项目结构2.模板工程定义描述文件3.子模块pom...
    99+
    2022-11-12
  • 手把手教你写一个spring IOC容器的方法
    本文分享自华为云社区《手把手教你写一个spring IOC容器》,原文作者:技术火炬手。 spring框架的基础核心和起点毫无疑问就是IOC,IOC作为spring容器提供的核心技术...
    99+
    2022-11-12
  • 手把手教你入门Python中的Web开发框架
    说到web开发框架,小编平常用Flask和Django的比较多,其中的Flask属于是轻量级的开发框架,写一个API接口也是十分地方便,不过今天我们要介绍的框架FastAPI同样在Python开发者当中有着较好地口碑,那么在开始之前,我们先...
    99+
    2023-05-14
    Python web 编程语言
  • 使用springmvc运行流程分析,手写spring框架尝试
    目录1.配置阶段2.初始化阶段3.运行阶段springMVC介绍以及执行流程什么是SpringMVC?SpringMVC的优势是什么?该文章主要是分析Springmvc启动的...
    99+
    2022-11-12
  • 手把手带你用Node手写WebSocket协议
    我们知道,http 是一问一答的模式,客户端向服务器发送 http 请求,服务器返回 http 响应。这种模式对资源、数据的加载足够用,但是需要数据推送的场景就不合适了。有同学说,http2 不是有 server push 么?那只是推资源...
    99+
    2023-05-14
    前端 JavaScript Node.js
  • 手把手教你写--FTP(基于python)
    ftp需求分析1. 多用户同时登陆(客户端合法性验证)2. 用户登陆,加密认证--(hamc or md5)3. 注册功能4. 上传/下载文件,保证文件一致性5. 不同用户家目录不同,且只能访问自己的家目录6. 对用户进行磁盘配额、不同用户...
    99+
    2023-01-30
    手把手教你 FTP python
  • 手把手教你怎么创建spring项目
    创建Spring项目 通过spring.io生成初始代码,配置如下 下载好会得到一个.zip文件,解压导入IDEA就可以开始了,这是基础的项目结构 让我们打开src/main/j...
    99+
    2022-11-12
  • 手把手教你用Vue3写播放器
    TODO实现播放/暂停;实现开始/结束时间及开始时间和滚动条动态跟随播放动态变化;实现点击进度条跳转指定播放位置;实现点击圆点拖拽滚动条。页面布局及 css 样式如下<template> <div class=&quo...
    99+
    2023-05-14
    vue3
  • Java开发之手把手教你搭建企业级工程SSM框架
    目录1.在IDEA界面中创建MavenWeb工程2.在pom.xml中添加如下相关依赖3.web.xml 配置 Spring MVC、Spring4.分别在main目录下创建reso...
    99+
    2022-11-12
  • 手写PHP API框架(一)之PSR规范
    本篇文章给大家带来了关于php的相关知识,其中主要跟大家聊一聊编码规范,也建议大家在开发中尽量遵循规范,感兴趣的朋友下面一起来看一下吧,希望对大家有帮助。创作初衷有没有用烦了CURD?各种框架是不是有点头大?有没有尝试自己设计一个框架?学了...
    99+
    2023-05-14
    php 编码规范
  • 手把手教你搭建vue3.0项目架构
    目录前言:一、用 vue-cli 创建项目二、安装路由三、完善目录结构,创建配置文件vue.config.js四、安装ant-design-vue,安装less、安装dayjs五、安...
    99+
    2022-11-12
  • 手把手教你从0搭建前端脚手架详解
    目录脚手架目录结构了解搭建的脚手架脚手架的初始化脚手架依赖安装询问用户问题创建入口文件最基本的交互命令简单介绍一下commander依赖常用的方法编写交互命令 create创建第一个...
    99+
    2023-05-14
    前端脚手架 JS前端脚手架 JS搭建脚手架
  • 手写java性能测试框架第二版
    目录引言第二版的threadbase代码如下固定次数模式的压测虚拟类固定时间模式虚拟类HTTPrequestbase为基础的多线程类固定次数模式的多线程类固定时间模式的多线程类使用D...
    99+
    2022-11-13
  • 手写PHP API框架(三)之反射介绍
    上一篇《手写PHP API框架之Composer的安装使用(二)》文章中我们介绍了Composer的安装使用,这一文我们来介绍一下有关反射的概念介绍。反射,直观理解就是根据到达地找到出发地和来源。 反射指在PHP运行状态中,扩展分析PHP程...
    99+
    2023-05-14
    php API 反射
  • 手写RPC框架,真不是为了装13!
    面试中,很容易被面试官问到:如何设计一个RPC框架?你可能没有被问到过,可能是运气好,也可能是你还没到这个级别。通常月薪20k以上,基本上都会问一些设计性的题目。站在面试官角度:问这类题目,总比一个八股文强,这里面会涉及到很多技术点。比如:...
    99+
    2023-08-16
  • 零基础手把手教你写NFT抢购软
    前言 由于之前写过几篇文章,但是个人不是很满意,所以这次我打算把所有的知识汇总成一篇文章。可能会有很多地方写的不是很好,欢迎大家评论指出,我后续修正。 个人vx:http://wc.ljlju.cn/...
    99+
    2023-08-31
    服务器 java 网络
  • 一起动手编写Android图片加载框架
    开发一个简洁而实用的Android图片加载缓存框架,并在内存占用与加载图片所需时间这两个方面与主流图片加载框架之一Universal Image Loader做出比较,来帮助我...
    99+
    2022-06-06
    框架 Android
  • 手把手带你实现一个萌芽版的Spring容器
    从什么是IOC开始? Spring——春天,Java编程世界的春天是由一位音乐家——Rod Johnson带来的。 Rod Johns...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作