nestjs中AOP的实现

nestjs中面向切面编程分为以下几个部分:中间件、Guard、Interceptor、Pipe、Filter


一、按照使用方式来分类:

1中间件:在模块的configure方法中进行配置,其配置是以代码形式进行的,当所有模块扫描完、组件创建之后,在NestApplication的setupModules方法中进行设置

2Guard、Interceptor、Pipe、Filter:使用装饰器在路由类、路由方法、路由方法参数上设置


二、按照实例获取方式来分类

1中间件:由于中间件类只出现在configure方法中,所以在之前扫描模块时并不知道这个类,只有当设置中间件时才会获取其实例,使用方法为:

@nestjs/core/injector/injector.ts
//加载中间件实例
  public async loadInstanceOfMiddleware(
    wrapper: MiddlewareWrapper,
    collection: Map<string, MiddlewareWrapper>,
    module: Module) {
    //中间件类型
    const { metatype } = wrapper;
    //中间件包装器
    const currentMetatype = collection.get(metatype.name);
    //如果包装器中已经有实例,直接返回
    if (currentMetatype.instance !== null) return;
    //如果实例不存在,解析构造函数参数,最后使用参数实例创建中间件实例,说明中间件也可以依赖注入
    await this.resolveConstructorParams(wrapper as any, module, null, null, (instances) => {
      collection.set(metatype.name, {
        instance: new metatype(...instances),
        metatype,
      });
    });
  }
可以看到,中间件对象也是使用注射器生成,说明它可以被注入组件,但是这一步与其他注入实例生成的时机是不一样的

2.Guard、Interceptor:UseGuards、UseInterceptors装饰器分别设置了他们的类,在扫描模块时扫描到这些元数据,并生成其实例,说明他们也是可以被注入组件的

@nestjs/core/injector/injector.ts

 //加载可注入类实例
  public async loadInstanceOfInjectable(wrapper: InstanceWrapper<Controller>, module: Module) {
    //获取可注入类Map
    const injectables = module.injectables;
    //加载实例
    await this.loadInstance<Controller>(wrapper, injectables, module);
  }
3.Filter、Pipe:UseFilters、UsePipes装饰器直接设置它们的实例,所以不能进行组件注入


三、按照切面位置来区分

所有的切面都是围绕着express来处理的

1.中间件:直接设置为express中间件,在其相应路由之前执行

2.Guard、Interceptor、Pipe:在创建路由方法上下文时,加入相应的执行方法

3.Filter:当路由执行方法抛出异常时,由过滤器处理

猜你喜欢

转载自blog.csdn.net/qq_27868061/article/details/79441034