NestJS中如何通过Provider获取类与方法装饰器的元数据?
实现方案
1. 先定义元数据常量(如果还未定义)
// 两个常量分别对应类装饰器@Exchange和方法装饰器@ExchangeRoute的元数据存储Key export const EXCHANGE_META_KEY = 'exchange.decorator.key'; export const EXCHANGE_ROUTE_META_KEY = 'exchange.route.decorator.key';
你需要保证自己实现的两个装饰器是通过Reflector/SetMetadata把元数据存在上面两个Key上。
2. 模块初始化阶段逻辑实现
import { EXCHANGE_META_KEY, EXCHANGE_ROUTE_META_KEY } from './constants'; @Module({}) class MyModule implements OnModuleInit{ // 注意先注入DiscoveryService constructor(private readonly discovery: DiscoveryService) {} async onModuleInit() { // 第一步:全局筛选所有带@Exchange类装饰器的Provider const exchangeProviders = await this.discovery.providersWithMetaAtKey(EXCHANGE_META_KEY); for (const providerItem of exchangeProviders) { // 读取类上的交换机配置,比如交换机名称 const exchangeConfig = providerItem.meta; // 第二步:仅在当前Provider范围内,查找所有带@ExchangeRoute装饰器的方法 const routeMethods = await this.discovery.providerMethodsWithMetaAtKey( EXCHANGE_ROUTE_META_KEY, // 筛选条件:只匹配当前遍历到的Provider (wrapper) => wrapper.name === providerItem.provider.name ); // 第三步:合并元数据,复用你原有的监听逻辑 for (const methodItem of routeMethods) { const routeConfig = methodItem.meta; // 合并类上的交换机配置和方法上的路由配置 const fullListenConfig = { exchange: exchangeConfig, queue: routeConfig.queue, routingKey: routeConfig.routingKey }; // 触发原有监听注册逻辑,执行方法时用如下调用保证this指向正确 // methodItem.discoveredMethod.handler.call(providerItem.provider.instance, msg) } } } }
补充说明
- 如果你已经给两个装饰器定义了其他元数据Key,直接替换上文的常量即可
- providerMethodsWithMetaAtKey的第二个筛选参数可以避免全局搜索,精准匹配当前Provider下的方法
- 原有注册队列、绑定交换机、消费消息的逻辑不需要改动,只需要替换元数据读取部分即可
内容的提问来源于stack exchange,提问作者Hiran Júnior
相关产品推荐
相关产品推荐

