VonaJS AOP編程:全局中間件全攻略
在VonaJS框架中,AOP編程包括三方面:控制器切面、內部切面和外部切面。控制器切面包括五能力:Middleware、Guard、Interceptor、Pipe、Filter。
其中,Middleware又分為:局部中間件、全局中間件和系統中間件。其時序圖如下所示:

由圖可知,系統中間件在路由匹配之前執行,局部中間件和全局中間件在路由匹配之后執行。
為了簡化起見,這里僅介紹全局中間件的用法,局部中間件和系統中間件的用法,請參見官方文檔。
創建中間件
比如,在模塊 demo-student 中創建一個 全局中間件: logger
1. Cli命令
$ vona :create:bean middleware logger --module=demo-student --boilerplate=cli/middlewareGlobal/boilerplate
2. 菜單命令
右鍵菜單 - [模塊路徑]: `Vona Aspect/Middleware Global`
中間件定義
export interface IMiddlewareOptionsLogger extends IDecoratorMiddlewareOptionsGlobal {}
@Middleware<IMiddlewareOptionsLogger>({ global: true })
export class MiddlewareLogger extends BeanBase implements IMiddlewareExecute {
async execute(_options: IMiddlewareOptionsLogger, next: Next) {
const timeBegin = Date.now();
const res = await next();
const timeEnd = Date.now();
console.log('time: ', timeEnd - timeBegin);
return res;
}
}
IMiddlewareOptionsLogger: 定義中間件參數execute: 輸出執行時長
使用中間件
與局部中間件不同,系統會自動加載全局中間件,并使其生效
中間件參數
可以為中間件定義參數,通過參數更靈活的配置中間件邏輯
比如,為 logger 中間件定義prefix參數,用于控制輸出格式
1. 定義參數類型
export interface IMiddlewareOptionsLogger extends IDecoratorMiddlewareOptionsGlobal {
+ prefix: string;
}
2. 提供參數缺省值
@Middleware<IMiddlewareOptionsLogger>({
global: true,
+ prefix: 'time',
})
3. 使用參數
export interface IMiddlewareOptionsLogger extends IDecoratorMiddlewareOptionsGlobal {
prefix: string;
}
@Middleware<IMiddlewareOptionsLogger>({
global: true,
prefix: 'time',
})
class MiddlewareLogger {
async execute(options: IMiddlewareOptionsLogger, next: Next) {
const timeBegin = Date.now();
const res = await next();
const timeEnd = Date.now();
- console.log('time: ', timeEnd - timeBegin);
+ console.log(`${options.prefix}: `, timeEnd - timeBegin);
return res;
}
}
4. 使用時指定參數
可以針對某個 API 單獨指定全局中間件的參數
+ import { Aspect } from 'vona-module-a-aspect';
class ControllerStudent {
@Web.get()
+ @Aspect.middlewareGlobal('demo-student:logger', { prefix: 'elapsed' })
async findMany() {}
}
- 在使用中間件時直接提供參數值即可
5. App config配置
可以在 App config 中配置中間件參數
src/backend/config/config/config.ts
// onions
config.onions = {
middleware: {
'demo-student:logger': {
prefix: 'elapsed',
},
},
};
6. 參數優先級
使用時指定參數 > App config配置 > 參數缺省值
中間件順序
由于全局中間件是默認加載并生效的,所以,VonaJS 提供了兩個參數,用于控制中間件的加載順序
1. dependencies
比如,系統有一個內置全局中間件a-core:gate,我們希望加載順序如下:a-core:gate > Current
@Middleware({
global: true,
+ dependencies: 'a-core:gate',
prefix: 'time',
})
class MiddlewareLogger {}
2. dependents
dependents的順序剛好與dependencies相反,我們希望加載順序如下:Current > a-core:gate
@Middleware({
global: true,
+ dependents: 'a-core:gate',
prefix: 'time',
})
class MiddlewareLogger {}
中間件啟用/禁用
可以針對某些 API 控制全局中間件的啟用/禁用
1. Enable
- 針對某個 API 禁用
class ControllerStudent {
@Web.get()
+ @Aspect.middlewareGlobal('demo-student:logger', { enable: false })
async findMany() {}
}
- 針對所有 API 禁用
src/backend/config/config/config.ts
// onions
config.onions = {
middleware: {
'demo-student:logger': {
+ enable: false,
},
},
};
2. Meta
可以讓全局中間件在指定的運行環境生效
| 名稱 | 類型 | 說明 |
|---|---|---|
| flavor | string|string[] | 參見: 運行環境與Flavor |
| mode | string|string[] | 參見: 運行環境與Flavor |
| instanceName | string|string[] | 參見: 多實例/多租戶 |
| host | string|string[] | 主機名 |
- 舉例
@Middleware({
global: true,
+ meta: {
+ flavor: 'normal',
+ mode: 'dev',
+ instanceName: '',
+ host: 'localhost:7102',
+ },
})
class MiddlewareLogger {}
3. match/ignore
可以針對指定的 API 啟用/禁用全局中間件
| 名稱 | 類型 | 說明 |
|---|---|---|
| match | string|regexp|(string|regexp)[] | 針對哪些API啟用 |
| ignore | string|regexp|(string|regexp)[] | 針對哪些API禁用 |
查看當前生效的全局中間件清單
可以直接在 Controller action 中輸出當前生效的全局中間件清單
class ControllerStudent {
@Web.get()
async findMany() {
+ this.bean.onion.middleware.inspect();
}
}
this.bean.onion: 取得全局 Service 實例onion.middleware: 取得與中間件相關的 Service 實例.inspect: 輸出當前生效的全局中間件清單
當訪問findMany API 時,會自動在控制臺輸出當前生效的全局中間件清單,效果如下:


在VonaJS框架中,AOP編程包括三方面:控制器切面、內部切面和外部切面??刂破髑忻姘ㄎ迥芰Γ篗iddleware、Guard、Interceptor、Pipe、Filter。其中,Middleware又分為:局部中間件、全局中間件和系統中間件。
浙公網安備 33010602011771號