生命周期
在通常情况下,我们希望在应用启动的时候做一些初始化、或者其他一些预处理的事情,比如创建数据库连接、预生成一些配置,而不是在请求响应时去处理。
项目生命周期
框架提供了这些生命周期函数供开发人员处理:
- 配置文件加载,我们可以在这里去修改配置(
onConfigLoad
) - 依赖注入容器准备完毕,可以在这个阶段做大部分的事情(
onReady
) - 服务启动完成,可以拿到 server(
onServerReady
) - 应用即将关闭,在这里清理资源(
onStop
)
Midway 的生命周期是通过 src/configuration.ts
文件,实现 ILifeCycle 接口,就可以在项目启动时候自动加载。
接口定义如下。
interface ILifeCycle {
/**
* 在应用配置加载后执行
*/
onConfigLoad?(container: IMidwayContainer, app: IMidwayApplication): Promise<void>;
/**
* 在依赖注入容器 ready 的时候执行
*/
onReady(container: IMidwayContainer, app: IMidwayApplication): Promise<void>;
/**
* 在应用服务启动后执行
*/
onServerReady?(container: IMidwayContainer, app: IMidwayApplication): Promise<void>;
/**
* 在应用停止的时候执行
*/
onStop?(container: IMidwayContainer, app: IMidwayApplication): Promise<void>;
/**
* 在健康检查时执行
*/
onHealthCheck?(container: IMidwayContainer): Promise<HealthResult>;
}
onConfigLoad
一般用于修改项目的配置文件。
举个例子。
// src/configuration.ts
import { Configuration, ILifeCycle, IMidwayContainer } from '@midwayjs/core';
@Configuration()
export class MainConfiguration implements ILifeCycle {
async onConfigLoad(): Promise<void> {
// 直接返回数据,会自动合并到配置中
return {
test: 1
}
}
}
这个时候,@Config
拿到的配置就包含了返回的数据,具体可以参考 异步初始化配置 章节。
onReady
onReady 是一个大部分场景下都会使用到的生命周期。
信息
注意,这里的 ready 指的是依赖注入容器 ready,并不是应用 ready,所以你可以对应用做任意扩展,比如添加中间件,连接数据库等等。
我们需要在初始化时提前连接一个数据库,由于在类中,所以也可以通过 @Inject
装饰器注入 db 这样一个数据库的连接工具类,这个实例包含 connect 和 close 两个函数:
// src/configuration.ts
import { Configuration, ILifeCycle, IMidwayContainer } from '@midwayjs/core';
@Configuration()
export class MainConfiguration implements ILifeCycle {
@Inject()
db: any;
async onReady(container: IMidwayContainer): Promise<void> {
// 建立数据库连接
await this.db.connect();
}
async onStop(): Promise<void> {
// 关闭数据库连接
await this.db.close();
}
}
这样,我们就能够在应用启 动时建立数据库连接,而不是在请求响应时再去创建。同时,在应用停止时,也可以优雅的关闭数据库连接。
除此之外,通过这个方式,可以对默认注入的对象做扩充。
// src/configuration.ts
import { Configuration, ILifeCycle, IMidwayContainer } from '@midwayjs/core';
import * as sequelize from 'sequelize';
@Configuration()
export class MainConfiguration implements ILifeCycle {
async onReady(container: IMidwayContainer): Promise<void> {
// 三方包对象
container.registerObject('sequelize', sequelize);
}
}
在其他的类中可以直接注入使用。
export class IndexHandler {
@Inject()
sequelize;
async handler() {
console.log(this.sequelize);
}
}
onServerReady
当要获取框架的服务对象,端口等信息时,就需要用到这个生命周期。
我们以 @midwayjs/koa
为例,在启动时获取它的 Server。
// src/configuration.ts
import { Configuration, ILifeCycle, IMidwayContainer } from '@midwayjs/core';
import * as koa from '@midwayjs/koa';
@Configuration({
imports: [koa]
})
export class MainConfiguration implements ILifeCycle {
async onServerReady(container: IMidwayContainer): Promise<void> {
// 获取到 koa 中暴露的 Framework
const framework = await container.getAsync(koa.Framework);
const server = framework.getServer();
// ...
}
}
onStop
我们可以在这个阶段清理一些资源,比如关闭连接等。
// src/configuration.ts
import { Configuration, ILifeCycle, IMidwayContainer } from '@midwayjs/core';
import * as koa from '@midwayjs/koa';
@Configuration({
imports: [koa]
})
export class MainConfiguration implements ILifeCycle {
@Inject()
db: any;
async onReady(container: IMidwayContainer): Promise<void> {
// 建立数据库连接
await this.db.connect();
}
async onStop(): Promise<void> {
// 关闭数据库连接
await this.db.close();
}
}