总体概念
在这里,我想对本章节做一个总结和简单的回顾。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)类的相关方法。例如:
上述程序的
onApplicationBootstrap
在初始化时会被执行到。但是,如果希望能在应用程序退出之前“优雅的”执行程序退出程序步骤,有两种方式:给进程发送SIGTERM
信号,或者执行app.close()
。前者可以利用Kubernates来管理容器的生命周期。Loading...