NestJs设计核心思想
> 转载请注明出处,原文 github 地址 [NestJs设计核心思想]github.com/ChoGathK/blogs/blob/master/src/history/NestJs设计思想.md
IoC (控制反转) & DI (依赖注入)
> 将应用程序赋予一个中心 ———— Ioc 容器
,并将被依赖对象的实例化过程提取到 Ioc 容器
中,由 Ioc 容器
管理依赖关系和被依赖对象的注入
控制反转
> 谁在控制谁?
我们直接 new 一个对象时,是程序应用在主动地创建;但是使用 IoC 模式开发时,会使用容器来负责这些对象的创建。这个时候是容器在控制对象。
> 反转了什么?
在传统的程序应用里面,我们在依赖类中会主动获取被依赖对象,而现在,这个过程反了过来。由容器管理被依赖对象,并注入到依赖类中。
> 描述
IoC
是一种方法论,一种工程化的思想。使用 IoC 意味着你将设计好的被依赖对象交给容器控制,而不是在对象内部直接控制
在 Nest.js
中,会把创建和查找 Providers
的控制权交给容器,由容器进行注入,所以对象与对象之间的耦合是松散的,有利于功能复用,更重要的是使得程序的整个结构变得非常灵活
依赖注入
> 描述
DI
指模块之间的依赖关系由容器规定,各个模块的依赖关系是由容器来注入的
在 Nest.js
中,开发者只需要通过在 Module
完成依赖关系的注册,并在类的 constructor
中声明即可,依赖类不关心被依赖对象来自何方,由谁实现
Nest.js 的实现方法
容器
: Nest.js 运行时
*被依赖对象: Providers (提供者/其他类的依赖)
-
模块
: Module (依赖注册器)-
Nest.js
运行前,对提供者类
、依赖类
进行依赖关系标记 -
Nest.js
运行时,遍历Module
中注册的标记,然后创建被依赖对象,将其缓存并返回,或者如果已经缓存,则返回现有实例
-
优点
-
让模块专注于设计任务
-
避免模块替换时的副作用
-
将执行任务和任务实现解耦
-
模块仅依赖于设计契约而无需关注其他系统如何工作
缺点
- 因为使用反射技术来创建被依赖对象,所以效率相对直接
new
要慢,而且创建被依赖实例的过程将变得复杂
AOP (面向切面编程)
> 从横向切面将相同的流程提取成 Middleware
(中间件),并根据不同的业务实现,细分成各种职责模块
核心思想
> 对哪些方法进行拦截,拦截后怎样处理。
-
Aspect 切面
- 切面是散落在系统各处通用的业务逻辑代码,如日志模块、权限模块、事务模块等。
- 切面用来装载 PointCut 和 Advice
- 切面通常是一个类,可以定义切入点和通知。类是对物体特征的抽象,切面是对横切关注点的抽象。
- 切面是业务流程运行的某个特定步骤,是应用运行过程中的关注点,关注点通常会横切多个对象,因此也被称为横切关注点。
-
JointPoint 连接点
- 连接点是程序执行过程中明确的点,一般是类中方法的调用。连接点是程序在运行过程中能够插入切面的地点,比如方法调用、异常抛出、字段修改等。
-
Advice 通知/增强
- 通知是AOP在特定切入点上执行的增强处理,是拦截到连接点之后要执行的代码,通知可以分为前置通知Before、后置通知AfterReturning、异常通知AfterThrowing、最终通知After、环绕通知Around五类。
-
PointCut 切入点
- 切入点是带有通知的连接点,在程序中主要体现为编写切入点表达式。切入点是对连接点进行拦截的定义。切入点用于定义通知应该切入到哪些连接点上,不同的通知需要切入到不同的连接点上,这种精准的匹配是由切入点的正则表达式来定义的。
- 切入点是可以插入增强处理的连接点,当某个连接点满足执行要求时,该连接点将被连接增强处理,该连接点也就变成了切入点。
- 切入点是拦截的方法,连接点JointPoint拦截后将变成切入点。
-
Proxy 代理对象
- 代理对象是AOP创建的对象,包含通知,代理是目标对象的加强。 代理是将通知应用到目标对象之后被动态创建的对象,可以简单理解代理对象的功能等同于目标对象的核心业务逻辑功能加上共有功能。代理对象对于使用者而言是透明的,是程序运行过程中的产物。
-
Weaving 织入
- 通过切入点切入,将切面应用到目标对象并导致代理对象创建的过程。将切面应用到目标对象从而创建一个新的代理对象的过程,这个过程可以发生在编译器、类转载期、运行期,不同的发生点有着不同的前提条件。如果发生在编译器就需要有一个支持这种AOP实现的特殊编译器,发生在类转载期就需要有一个支持AOP实现的特殊类转载其,发生在运行期则可以直接通过反射机制与动态代理机制来动态实现。
-
Target 目标对象
- 目标对象是指代理的目标对象,是指要织入的对象模块。目标对象是那些即将切入切面的对象,也就是被通知的对象。这些对象中已经只剩下干干净净的核心业务逻辑代码,所有的共有功能等待AOP容器的切入。
- 目标对象是AOP进行增强处理的对象,也被称为增强的对象。如果AOP是通过运行时代理来实现的,那么这个对象将是一个被代理的对象。