如何在NestJS中确保带依赖注入的拦截器执行顺序?
解决NestJS拦截器执行顺序问题
要确保DataConsistencySourceSetter先执行,再执行DataConsistencyChecker,可以通过反射元数据+DI管理拦截器的方式来实现,避免手动实例化拦截器导致的顺序异常。
具体步骤
1. 创建自定义元数据装饰器
用于传递数据源参数,替代原工厂函数的参数传递方式:
import { SetMetadata } from '@nestjs/common'; // 定义元数据标识key export const CONSISTENCY_SOURCES_KEY = 'consistency_sources'; // 自定义装饰器,接收数据源数组 export const SetConsistencySources = (sources: Sources[]) => SetMetadata(CONSISTENCY_SOURCES_KEY, sources);
2. 修改DataConsistencySourceSetter拦截器
通过Reflector获取元数据中的数据源,不再通过构造函数传入:
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, Reflector } from '@nestjs/common'; import { Observable } from 'rxjs'; @Injectable() export class DataConsistencySourceSetter implements NestInterceptor { constructor(private readonly reflector: Reflector) {} intercept(context: ExecutionContext, next: CallHandler<any>): Observable<any> { logger.debug("Entered DataConsistencySourceSetter"); const req = context.switchToHttp().getRequest(); // 从当前请求的处理方法上获取元数据中的数据源 const sources = this.reflector.get<Sources[]>( CONSISTENCY_SOURCES_KEY, context.getHandler() ); req.sources = sources; return next.handle(); } }
3. 调整控制器的拦截器使用方式
使用自定义装饰器传递数据源,并确保两个拦截器按顺序声明:
@Controller('payment') @UseInterceptors(HttpResponseTransferInterceptor) @UseFilters(HttpExceptionFilter) export class ApiController { // ... 构造函数略 @Get() // 用自定义装饰器设置当前接口的数据源 @SetConsistencySources([Sources.LOAN]) // 按需求顺序声明拦截器,SourceSetter在前,Checker在后 @UseInterceptors(DataConsistencySourceSetter, DataConsistencyChecker) async getState(@Query() requestDto: PaymentStateRequestDto, @Req() req: any) { const result = await this.apiService.fetchPaymentStates(requestDto); return result.map(r => plainToInstance(PaymentStateResponseDto, r)); } }
原问题原因
你之前的写法中,DataConsistencySourceSetter是通过工厂函数手动实例化的对象,而DataConsistencyChecker是由Nest DI容器管理的类。当混合传递实例和类到@UseInterceptors时,Nest的DI容器会优先解析并执行类类型的拦截器,导致顺序反转。改用DI管理的拦截器+元数据传递参数后,拦截器会严格按照@UseInterceptors中的声明顺序执行,保证请求先经过DataConsistencySourceSetter设置数据源,再进入DataConsistencyChecker做一致性校验。
内容的提问来源于stack exchange,提问作者jnvsumit
相关产品推荐
相关产品推荐

