深入了解Nest的阶段性总结

2,255 阅读5分钟

在这里,我想对本章节做一个总结和简单的回顾。Nest绝大部分常用技术点都在本章中介绍到,那些元素相对独立,在一些特定需求中又需要相互配合才能完成一些特定逻辑任务。

静态架构

如果将Nest分为动态和静态两个维度观察,静态部分就有Provider(一般的功能)、Module(模块)和Decorator(装饰器)三个关键概念。其中Provider用于完成具体的业务逻辑。Module将各种业务逻辑以及相互之间的依赖关系,以IoC架构将其组装在一起。Decorator则将部分公共业务以装饰器(这种特殊的函数形态)封装在另外一块代码中。

模块、Provider、控制器类和装饰器关系

Nest是一个IoC容器。一个模块相当于一个群组,这个群组中的各个组件通过@Injectable()装饰器来标记出,并在初始化时注入到依赖的对象中。控制器是一种特殊的Provider,完成特定的功能。一般的服务类、工具类等等,都可以归纳到Provider中。

注入对象的托管,托管的范围

但凡是@Injectable()装饰的对象,都交给Nest来托管。托管后有的生命周期有三种类型(通过@Injectable()参数来定义),默认情况下同应用程序的生命周期,即:初始化时被初始化,应用程序退出后销毁;第二种是每个请求都会生成一个实例,比较占用内存,且低效;第三种是每个以来方会使用一个实例。

动态概念

执行过程

从前端浏览器响应开始,到Nest最后响应返回,经历以下过程:

summary.png

对象差异

类型声明方式使用方式接口或基类实现名称可访问对象作用对象
中间件类、函数模块中组装NestMiddlewareuse(requires,next)Request/Response/Next路径(映射)
异常过滤器装饰器ExceptionFiltercatch(exception,host)ArgumentsHost全局、控制器、方法
管道装饰器PipeTransformtransform(value,metadata)参数以及参数元数据全局、控制器、方法、参数
守卫装饰器CanActivatecanActivate(context)ExecutionContext全局、控制器、方法
拦截器装饰器NestInterceptorintercept(context,next)ExecutionContext全局、控制器、方法

平台无关性和可移植性

还是需要强调一开头强调过的,Nest并不是一个Web框架,而是一个IoC容器,也是一种开发哲学。真正的业务是由底层的Web框架去完成的。默认情况下,包括我在这里的案例,绝大多数都是以Express作为底层来实现的。甚至你可以自己构建一个以KoA为底层的(虽然没多大意义)Nest出来。所以,在处理某些细节方面,尤为需要注意底层的区别。比如在处理ExecutionContext对象时,要getType()判断究竟是那种类型的连接。

生命周期

Nest应用程序的生命周期大致可以分为:初始化运行时结束中三个阶段;这三个阶段在整个生命周期中会执行以下特殊方法

钩子方法说明
onModuleInit()模组的依赖被解析完后执行(REQUEST作用域下无效)
onApplicationBootstrap()所有模组被初始化完成后,在监听端口之前执行
onModuleDestory()收到终止信号,模组开始销毁之前执行
beforeApplicationShutdown()模块销毁过程执行完毕(不论是否成功),一旦完成过程,所有监听的连接会被关闭
onApplicationShutdown()连接关闭后执行

流程图:

summary_lifesequence.png

需要补充一下:在生命周期的重要节点中,Nest会自动调用(如果存在)模组、Provider和控制器或其他由Nest托管的(@Injectable)类的相关方法。例如:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {
  onApplicationBootstrap() {
    console.log('App Module启动');
  }
}

上述程序的onApplicationBootstrap 在初始化时会被执行到。但是,如果希望能在应用程序退出之前“优雅的”执行程序退出程序步骤,有两种方式:给进程发送SIGTERM信号,或者执行app.close()。前者可以利用Kubernates来管理容器的生命周期。

与官方文档对应

如果将至今我发表的关于Nest的一一比对Nest官方的文档,大概是这个样子的:第一章对应官方文档概览中的Fist stepsControllers以及部分其他少部分内容;第二章对应官方文档概览Controllers技术中的CookiesSession安全中的授权和认证部分内容;第三章对应官方文档概览中其余内容以及基础中的大部分内容。

在刚刚接触Nest时,曾经仔细阅读了官方文档,发现太模糊且凌乱,无论是谷歌还是百度,都鲜有详细的介绍。但是经验告诉我,Nest是一个优秀的框架(被人评定为Node JS在2021年第三大流行框架)所以花费了不少的心思仔细研究。最终呈现在大家眼前一系列文章。基本上所有常用、关键的内容已经全部介绍完毕(95%+)。未来也许还会继续写,那么应该一些其他IoC容器的应用或者经验上怎么使用Nest了吧。总之现在还没想的特别清楚,也许你可以给我一些思路,告诉我深入还有什么可挖的东西?

先到这里,谢谢大家~! (未完待续)