NestJS微服务中如何通过请求作用域提供者获取ExecutionContext?
获取请求作用域的ExecutionContext服务实现
要实现类似请求作用域获取Request那样获取ExecutionContext,可以通过请求作用域服务+全局拦截器的组合来完成,具体步骤如下:
1. 创建请求作用域的ExecutionContext服务
这个服务负责存储和提供当前请求的ExecutionContext,利用REQUEST令牌绑定到当前请求上下文:
import { Injectable, Scope, Inject } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; import { ExecutionContext } from '@nestjs/common'; @Injectable({ scope: Scope.REQUEST }) export class ExecutionContextService { private executionContext: ExecutionContext; constructor(@Inject(REQUEST) private readonly request: Request) {} setExecutionContext(context: ExecutionContext): void { this.executionContext = context; // 可选:将Context挂载到request对象,方便其他地方直接取用 (this.request as any).executionContext = context; } getExecutionContext(): ExecutionContext { return this.executionContext || (this.request as any).executionContext; } }
2. 实现全局拦截器注入ExecutionContext
通过全局拦截器,在每个请求进入时将ExecutionContext传递给上面的请求作用域服务:
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common'; import { Observable } from 'rxjs'; import { ExecutionContextService } from './execution-context.service'; @Injectable() export class ExecutionContextInterceptor implements NestInterceptor { constructor(private readonly executionContextService: ExecutionContextService) {} intercept(context: ExecutionContext, next: CallHandler): Observable<any> { this.executionContextService.setExecutionContext(context); return next.handle(); } }
3. 注册服务与全局拦截器
在模块中注册服务,并将拦截器设置为全局生效:
import { Module } from '@nestjs/common'; import { APP_INTERCEPTOR } from '@nestjs/core'; import { ExecutionContextService } from './execution-context.service'; import { ExecutionContextInterceptor } from './execution-context.interceptor'; @Module({ providers: [ ExecutionContextService, { provide: APP_INTERCEPTOR, useClass: ExecutionContextInterceptor, }, ], exports: [ExecutionContextService], // 导出供其他模块使用 }) export class SharedModule {}
4. 在业务服务中使用
现在可以在任意服务中注入ExecutionContextService,获取当前请求的ExecutionContext:
import { Injectable } from '@nestjs/common'; import { ExecutionContextService } from './execution-context.service'; @Injectable() export class BusinessService { constructor(private readonly ecService: ExecutionContextService) {} handleRequest() { const context = this.ecService.getExecutionContext(); // 根据请求类型切换上下文,这里以HTTP为例 const request = context.switchToHttp().getRequest(); const response = context.switchToHttp().getResponse(); console.log('当前请求路径:', request.url); // 可以根据需要使用Context的其他能力,比如判断请求类型、获取RPC参数等 } }
原理说明
ExecutionContextService是请求作用域,每个请求都会生成独立实例,确保ExecutionContext不会跨请求污染。- 全局拦截器在请求生命周期的最开始触发,将当前请求的
ExecutionContext注入到服务中,后续业务逻辑就能随时获取。
内容的提问来源于stack exchange,提问作者chirag thapa
相关产品推荐
相关产品推荐

