全局模块
module 导出 provider,另一个 module 需要 imports 它才能用这些 provider。
如果这个模块被很多模块依赖,那每次都要 imports 就很麻烦。
能不能设置成全局的,它导出的 provider 直接可用呢?
1.常用引入模块方式
在 AaaModule 里指定 exports 的 provider
然后,在 BbbModule 里 imports
这样就可以在 BbbService 内注入 AaaService
2.@Global() 将模块声明为全局的
在 AaaModule 上加一个 @Global 的装饰器,然后,在 BbbModule 里把 AaaModule 的 imports 去掉。
依然可以注入AaaService
全局模块要尽量少用,不然,注入的很多 provider 都不知道来源,会降低代码的可维护性
生命周期
Module, Controller, Provider 是由 nest 创建的,能不能在创建,销毁时执行一些逻辑呢?
nest 在启动的时候,会递归解析 Module 依赖,扫描其中的 provider,controller,注入它的依赖。 全部解析完后,会监听网络端口,开始处理请求。 这个过程中,nest 暴漏了一些生命周期方法

1.创建阶段
nest 提供了两个 interface
1
2
3
4
5
6
7
8
export interface OnModuleInit {
onModuleInit(): any;
}
export interface OnApplicationBootstrap {
onApplicationBootstrap(): any;
}
在 controller,service,module 中分别实现它们:
然后,重新运行服务,会看到下面的日志信息,显示了生命周期方法的调用顺序
2.销毁阶段
1.先调用 每个模块的 contoller,provider 的 onModuleDestroy 方法, 然后,调用 Module 的 onModuleDestroy。
2.之后,再调用每个模块的 controller,provider 的 beforeApplicationShutdown 方法, 然后,调用 Module 的 beforeApplicationShutdown 方法。
3.然后,停止监听网络端口。
4.之后,调用每个模块 controller,provider 的 onApplicationShutdown 方法, 然后,调用 Module 的 onApplicationShutdown 方法。
5.之后停止进程。
onModuleDestroy 和 beforeApplicationShutdown 的区别
1
2
3
4
5
6
7
8
9
export interface OnModuleDestroy {
onModuleDestroy(): any;
}
export interface BeforeApplicationShutdown {
beforeApplicationShutdown(signal?: string): any; // 可以拿到 signal 系统信号,比如:SIGTERM
}
这些终止信号是别的进程传过来的,让它做一些销毁的事情,比如k8s管理容器的时候,可以通过这个信号来通知它。
3秒后,调用 app.close() (只是触发销毁逻辑,不会真正退出进程)
生命周期方法执行顺序
所有的生命周期方法都支持 async
生命周期用法举例:
一般都通过 moduleRef 取出一些 provider 来销毁,比如关闭连接。