在这里,我想对本章节做一个总结和简单的回顾。Nest绝大部分常用技术点都在本章中介绍到,那些元素相对独立,在一些特定需求中又需要相互配合才能完成一些特定逻辑任务。
静态架构
如果将Nest分为动态和静态两个维度观察,静态部分就有Provider(一般的功能)、Module(模块)和Decorator(装饰器)三个关键概念。其中Provider用于完成具体的业务逻辑。Module将各种业务逻辑以及相互之间的依赖关系,以IoC架构将其组装在一起。Decorator则将部分公共业务以装饰器(这种特殊的函数形态)封装在另外一块代码中。
模块、Provider、控制器类和装饰器关系
Nest是一个IoC容器。一个模块相当于一个群组
,这个群组中的各个组件通过@Injectable()
装饰器来标记出,并在初始化时注入到依赖的对象中。控制器是一种特殊的Provider,完成特定的功能。一般的服务类、工具类等等,都可以归纳到Provider中。
注入对象的托管,托管的范围
但凡是@Injectable()
装饰的对象,都交给Nest来托管。托管后有的生命周期有三种类型(通过@Injectable()
参数来定义),默认情况下同应用程序的生命周期,即:初始化时被初始化,应用程序退出后销毁;第二种是每个请求都会生成一个实例,比较占用内存,且低效;第三种是每个以来方会使用一个实例。
动态概念
执行过程
从前端浏览器响应开始,到Nest最后响应返回,经历以下过程:
对象差异
类型 | 声明方式 | 使用方式 | 接口或基类 | 实现名称 | 可访问对象 | 作用对象 |
---|---|---|---|---|---|---|
中间件 | 类、函数 | 模块中组装 | NestMiddleware | use(requires,next) | Request/Response/Next | 路径(映射) |
异常过滤器 | 类 | 装饰器 | ExceptionFilter | catch(exception,host) | ArgumentsHost | 全局、控制器、方法 |
管道 | 类 | 装饰器 | PipeTransform | transform(value,metadata) | 参数以及参数元数据 | 全局、控制器、方法、参数 |
守卫 | 类 | 装饰器 | CanActivate | canActivate(context) | ExecutionContext | 全局、控制器、方法 |
拦截器 | 类 | 装饰器 | NestInterceptor | intercept(context,next) | ExecutionContext | 全局、控制器、方法 |
平台无关性和可移植性
还是需要强调一开头强调过的,Nest并不是一个Web框架,而是一个IoC容器,也是一种开发哲学。真正的业务是由底层的Web框架去完成的。默认情况下,包括我在这里的案例,绝大多数都是以Express作为底层来实现的。甚至你可以自己构建一个以KoA为底层的(虽然没多大意义)Nest出来。所以,在处理某些细节方面,尤为需要注意底层的区别。比如在处理ExecutionContext
对象时,要getType()
判断究竟是那种类型的连接。
生命周期
Nest应用程序的生命周期大致可以分为:初始化
,运行时
,结束中
三个阶段;这三个阶段在整个生命周期中会执行以下特殊方法
钩子方法 | 说明 |
---|---|
onModuleInit() | 模组的依赖被解析完后执行(REQUEST作用域下无效) |
onApplicationBootstrap() | 所有模组被初始化完成后,在监听端口之前执行 |
onModuleDestory() | 收到终止信号,模组开始销毁之前执行 |
beforeApplicationShutdown() | 模块销毁过程执行完毕(不论是否成功),一旦完成过程,所有监听的连接会被关闭 |
onApplicationShutdown() | 连接关闭后执行 |
流程图:
需要补充一下:在生命周期的重要节点中,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 steps
,Controllers
以及部分其他少部分内容;第二章对应官方文档概览
中Controllers
、技术
中的Cookies
、Session
和安全
中的授权和认证部分内容;第三章对应官方文档概览
中其余内容以及基础
中的大部分内容。
在刚刚接触Nest时,曾经仔细阅读了官方文档,发现太模糊且凌乱,无论是谷歌还是百度,都鲜有详细的介绍。但是经验告诉我,Nest是一个优秀的框架(被人评定为Node JS在2021年第三大流行框架)所以花费了不少的心思仔细研究。最终呈现在大家眼前一系列文章。基本上所有常用、关键的内容已经全部介绍完毕(95%+)。未来也许还会继续写,那么应该一些其他IoC容器的应用或者经验上怎么使用Nest了吧。总之现在还没想的特别清楚,也许你可以给我一些思路,告诉我深入还有什么可挖的东西?
先到这里,谢谢大家~! (未完待续)