【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--控制器和处理函数的注册篇(4/8)【controller+action】

简介: 文章目录前情概要前边的文章把一些基本的前置任务都完成了。接下就是比较重要的处理函数action是如何自动发现和注册的拉,也就是入口函数RouteHandler(也是我们的第一个express中间件)里面的一些细节。

文章目录

前情概要

前边的文章把一些基本的前置任务都完成了。接下就是比较重要的处理函数action是如何自动发现和注册的拉,也就是入口函数RouteHandler(也是我们的第一个express中间件)里面的一些细节。

扫描action并添加到缓存

说一说我们的思路,其实和静态语言中的反射概念有点类似。

  1. 循环传进来的所有controller声明。详见 控制器的声明和定义篇---controller注册到RouteHandler
  2. 循环所有声明的controllers,并将每一个controller里面的action添加到action缓存中。

关键方法也就是Object.getOwnPropertyNames和Object.getOwnPropertyDescriptor2个方法了。目的则是对象上的所有成员,对应到比如说.net,java之类的就是反射拉。

export function RouteHandler(app: core.Express, controllers: any) {
    find(controllers)
    //app.use('/', (req, res, next) => 。。。。。。
}
function find(controllers: any) {
   //controllers本质上是一个对象,类似:{host:{},home:{},site:{}}。那我们这里的key就是controller的名字,value就是controller实列了。
    var _reg_controller_names = Object.getOwnPropertyNames(controllers)//对象上所有成员,就是我们所有的controller名称集合。
    for (var index = 0; index < _reg_controller_names.length; index++) {
        var _reg_controller_name = _reg_controller_names[index];//controller的名称,比如:home
        var _reg_controller_Desc = Object.getOwnPropertyDescriptor(controllers, _reg_controller_name) as PropertyDescriptor//controller的描述对象
        if (_reg_controller_name === '__esModule') continue;

        var cType = _reg_controller_Desc.value;//controller的类型,比如:Homecontroller
        var cName = cType.name;//controller的class名称。比如"HomeController";

        var aNames = Object.getOwnPropertyNames(cType.prototype)//controller所有成员,也就是我们的action
        for (var index2 = 0; index2 < aNames.length; index2++) {
            var aName = aNames[index2];
            if (aName === 'constructor') continue;
            var aType = (Object.getOwnPropertyDescriptor(cType.prototype, aName) as PropertyDescriptor).value//具体的每一个action函数
            SetActionDescriptor(cName, aName, undefined, undefined, _reg_controller_name, cType, aType)//加入缓存
            //第三个参数[httpMethod] 请求方法类型。默认给undefined,后续再通过扫描action上面的特性标签增加进来
            //第四个参数 [actionName] 路由action名字。默认给undefined,后续再通过扫描action上面的特性标签增加进来
        }
    }
}

SetActionDescriptor的实现

/**
 *
 *
 * @export
 * @param {string} controllerTypeName 控制器类型名字
 * @param {string} actionTypeName 方法类型名字
 * @param {string} [httpMethod] 请求方法类型
 * @param {string} [actionName] 路由action名字
 * @param {string} [controllerName] 路由控制器名字
 * @param {*} [controllerType] 控制器对象
 * @param {*} [actionType] action 对象
 * @returns {ActionDescriptor}
 */
export function SetActionDescriptor(controllerTypeName: string, actionTypeName: string, httpMethod?: string, actionName?: string, controllerName?: string, controllerType?: any, actionType?: any, isAuth?: boolean): ActionDescriptor {

    var _actions = _dic_override.get(controllerTypeName)
    if (!_actions) {
        _actions = new Map<string, ActionDescriptor>();
        _dic_override.set(controllerTypeName, _actions)
    }
    var _action = _actions.get(actionTypeName);
    if (!_action) {
        _action = new ActionDescriptor();
        _actions.set(actionTypeName, _action)
    }
    _action.ControllerTypeName = controllerTypeName;
    _action.ActionTypeName = actionTypeName;

    if (!_action.ActionName)
        _action.ActionName = actionTypeName

    if (httpMethod)
        _action.HttpMethod = httpMethod.toUpperCase();

    if (controllerType)
        _action.ControllerType = controllerType;
    if (controllerName)
        _action.ControllerName = controllerName;

    if (actionName)
        _action.ActionName = actionName;
    if (actionType)
        _action.ActionType = actionType

    if (isAuth === true || isAuth === false)
        _action.isAuth = isAuth;

    _action.Id = _action.ActionName + (_action.HttpMethod ? ('_' + _action.HttpMethod) : '')

    return _action
}

SetActionDescriptor方法参数有值得情况下则更新,没有值则跳过。因为针对同一个action可能会被调用多次。对一个action的描述信息也是分部分分多次set进来的。一部分是通过对象的原型,还有一部分则是ts的装饰器(后端语言的attribute)。
需要注意的是每个action有个id字段。id字段使用http method和action name 来拼接。

目录
相关文章
|
8月前
|
监控 Java 应用服务中间件
低并发编程|如何用720个请求让后端服务器瘫痪
本次故障因应用启动时未有效校验核心依赖模块初始化异常,导致后续请求处理中抛出无法捕获的错误,引发线程阻塞,最终耗尽HSF线程池,服务不可用。排查发现类初始化失败且异常未被正确处理,结合线程无限等待问题,确认为依赖初始化异常与流处理中断所致。修复措施包括加强启动校验、捕获Throwable及设置合理超时。总结指出,系统稳定性需从细节入手,防微杜渐,避免连锁故障。
低并发编程|如何用720个请求让后端服务器瘫痪
|
开发框架 .NET 开发者
简化 ASP.NET Core 依赖注入(DI)注册-Scrutor
Scrutor 是一个简化 ASP.NET Core 应用程序中依赖注入(DI)注册过程的开源库,支持自动扫描和注册服务。通过简单的配置,开发者可以轻松地从指定程序集中筛选、注册服务,并设置其生命周期,同时支持服务装饰等高级功能。适用于大型项目,提高代码的可维护性和简洁性。仓库地址:&lt;https://github.com/khellang/Scrutor&gt;
473 5
|
Web App开发 JavaScript 前端开发
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念,包括事件驱动、单线程模型和模块系统;探讨其安装配置、核心模块使用、实战应用如搭建 Web 服务器、文件操作及实时通信;分析项目结构与开发流程,讨论其优势与挑战,并通过案例展示 Node.js 在实际项目中的应用,旨在帮助开发者更好地掌握这一强大工具。
516 1
|
前端开发 Java 数据库连接
Spring MVC 扩展和SSM框架整合
通过以上步骤,我们可以将Spring MVC扩展并整合到SSM框架中。这个过程包括配置Spring MVC和Spring的核心配置文件,创建控制器、服务层和MyBatis的Mapper接口及映射文件。在实际开发中,可以根据具体业务需求进行进一步的扩展和优化,以构建更加灵活和高效的企业级应用程序。
316 5
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
569 5
|
存储 JavaScript 前端开发
深入浅出Node.js后端开发
在数字化时代的浪潮中,后端开发作为连接用户与数据的桥梁,扮演着至关重要的角色。本文将以Node.js为例,深入探讨其背后的哲学思想、核心特性以及在实际项目中的应用,旨在为读者揭示Node.js如何优雅地处理高并发请求,并通过实践案例加深理解。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和思考。
|
Web App开发 开发框架 JavaScript
深入浅出Node.js后端开发
在这篇文章中,我们将一起探索Node.js的奇妙世界。无论你是刚接触后端开发的新手,还是希望深化理解的老手,这篇文章都适合你。我们将从基础概念开始,逐步深入到实际应用,最后通过一个代码示例来巩固所学知识。让我们一起开启这段旅程吧!
|
JavaScript 前端开发 API
深入理解Node.js事件循环及其在后端开发中的应用
本文旨在揭示Node.js的核心特性之一——事件循环,并探讨其对后端开发实践的深远影响。通过剖析事件循环的工作原理和关键组件,我们不仅能够更好地理解Node.js的非阻塞I/O模型,还能学会如何优化我们的后端应用以提高性能和响应能力。文章将结合实例分析事件循环在处理大量并发请求时的优势,以及如何避免常见的编程陷阱,从而为读者提供从理论到实践的全面指导。
|
Web App开发 开发框架 JavaScript
深入浅出Node.js后端开发
本文将带你领略Node.js的魅力,从基础概念到实践应用,一步步深入理解并掌握Node.js在后端开发中的运用。我们将通过实例学习如何搭建一个基本的Web服务,探讨Node.js的事件驱动和非阻塞I/O模型,以及如何利用其强大的生态系统进行高效的后端开发。无论你是前端开发者还是后端新手,这篇文章都会为你打开一扇通往全栈开发的大门。
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端开发
本文将带你走进Node.js的世界,从基础到进阶,逐步解析Node.js在后端开发中的应用。我们将通过实例来理解Node.js的异步特性、事件驱动模型以及如何利用它处理高并发请求。此外,文章还会介绍如何搭建一个基本的Node.js服务器,并探讨如何利用现代前端框架与Node.js进行交互,实现全栈式开发。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和深入的理解。
516 4

热门文章

最新文章