Nestjs的全局模块和生命周期

981 阅读3分钟

1. 全局模块出现的原因

模块导出provider,而另一个模块要使用时必须imports之后才能使用。如果这个模块被很多模块依赖,那每次都需要imports,这样就比较麻烦。这时全局模块就出现了,它导出的provider可以直接使用。

2.常用引用方式

首先创建两个模块

nest g resource aaa
nest g res bbb

然后在aaa.module文件中导出(exports)aaa模块的providerimage.png

然后在bbb.moudule中将其引入(imports) image.png

最后在bbb.service中注入,调用aaa.service中的方法 image.png

进入/bbb路由,刷新页面,查看页面内容展示,可以看到属于aaa.service的的方法返回的信息也展示了出来。 image.png

这就是我们平常使用的引入Module的方式

3.全局模块

如果这个AaaModule被很多个模块引用,可以将其设置为全局模块,这样其他模块在引用时就避免了在本模块的module文件中进行引入了。 如何将模块生命为全局模块?只需要在模块上加一个@Global装饰器就可以了,如下: image.png

然后将BbbModule中引入的AaaModule删除: image.png

之后继续刷新页面,访问 http://localhost:3000/bbb 我们仍然可以访问到aaa.service.ts中的接口方法 image.png image.png 注:全局模块还是尽量少用,不然注入的很多 provider 都不知道来源,会降低代码的可维护性。

4.生命周期

生命周期方法: image.png

项目初始化流程:首先会递归初始化模块,依次调用模块内的controllerprovider的onModuleInit方法,然后再调用moduleonModuleInit方法。
初始化完成后会再次依次调用controllerprovider中的onApplicationBootstrap方法,然后调用module中的onApplicationBootstrap方法。
整个过程如下: image.png 现在来实现这两个api走下这整个流程。

我们还是使用上面建的aaabbb两个module
在aaa、bbb两个模块中的controller、service、module中分别实现: image.png image.png image.png bbb模块也按照同样的方法处理,然后重新启动服务,可以看到控制台打印的消息如下: image.png

应用销毁流程: 应用销毁时先调用每个modulecontrollerprovideronModuleDestroy方法,然后调用ModuleonModuleDestroy方法。
之后再调用每个modulecontrollerproviderbeforeApplicationShutdown方法,然后调用ModulebeforeApplicationShutdown方法。
然后停止监听网络端口。 之后再调用每个modulecontrollerprovideronApplicationShutdown方法,然后调用ModuleonApplicationShutdown方法。
最后就停止进程了。流程图如下:
image.png onModuleDestroybeforeApplicationShutdown的区别:
看下两个api对应的interface: image.png image.png 可以看到beforeApplicationShutdown是可以接收到signal信号的,拿到这个信息可以用来做一些事情。

接下来分别给aaabbb模块下的controllerserviccemodule加上应用销毁时的api方法。

controller image.png

service image.png

module image.png

修改项目的main.ts文件,在项目启动3s后调用app.close()触发销毁流程。(实际并不会真正退出进程)。日志流程打印如下: image.png