news 2026/6/25 0:19:04

AOP编程有三大场景:控制器切面,内部切面,外部切面,你get到了吗?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AOP编程有三大场景:控制器切面,内部切面,外部切面,你get到了吗?

果用过NestJS框架都知道,在NestJS框架中AOP编程包括以下几个能力:Middleware、Guard、Interceptor、Pipe、Filter。事实上AOP编程的应用场景更广泛,上述所列5个能力仅仅是AOP编程的子集。下面,我们看看在VonaJS框架中,AOP编程是怎样的。

VonaJS AOP编程

VonaJS AOP 编程包括三个方面的能力:

控制器切面: 为 Controller 方法切入逻辑

内部切面: 在 Class 内部,为任何 Class 的任何方法切入逻辑

外部切面: 在不改变 Class 源码的前提下,从外部为任何 Class 的任何方法切入逻辑

控制器切面

控制器切面清单

Middleware

Guard

Intercepter

Pipe

Filter

执行时序图

控制器切面的执行时序图如下:

aspect-controller

洋葱模型: Middleware和Intercepter支持洋葱模型,允许在Controller Action之前和之后执行切面逻辑

Middleware: 针对不同的执行时序节点,系统提供了三种 Middleware: Middleware System、Middleware Global和Middleware Local,从而可以实现更精细化的切面逻辑

Route Match: 只有Middleware System在路由匹配之前执行,其余在路由匹配之后执行

Filter: 任何环节抛出异常,都会执行Filter,从而自定义错误信息和错误日志的处理逻辑

内部切面

内部切面提供两个机制:AOP Method和魔术方法

1. AOP Method

直接在 Class Method 上通过装饰器切入逻辑

举例:数据库事务

class ServiceStudent {

+ @Database.transaction()

async update(id: TableIdentity, student: DtoStudentUpdate) {

return await this.scope.model.student.updateById(id, student);

}

}

@Database.transaction:通过AOP Method机制实现的装饰器,可以直接提供数据库事务能力

举例:日志

class ServiceStudent {

+ @Log()

async update(id: TableIdentity, student: DtoStudentUpdate) {

return await this.scope.model.student.updateById(id, student);

}

}

@Log:通过AOP Method机制实现的装饰器,可以直接提供日志能力

2. 魔术方法

可以在 Class 内部通过__get__和__set__切入动态属性或方法

举例:获取 model 实例

class ServiceStudent {

async update(id: TableIdentity, student: DtoStudentUpdate) {

+ return await this.scope.model.student.updateById(id, student);

}

}

this.scope.model.xxx: 没有使用依赖注入,而是使用依赖查找,直接通过 scope 对象获取 model 实例,从而简化代码的书写风格

实现思路

系统提供了一个 Class ServiceModelResolver,用于实现 model 实例的动态解析,代码如下:

class ServiceModelResolver {

protected __get__(prop: string) {

const beanFullName = `${this[SymbolModuleScope]}.model.${prop}`;

return this.bean._getBean(beanFullName as any);

}

}

当调用this.scope.model.student时,会自动执行__get__方法,并且传入参数prop: 'student'

将参数prop与当前模块名称合并成beanFullName

通过beanFullName从全局容器中获取 model 实例,并返回给调用者

外部切面

仍以 Class ServiceStudent的update方法为例,通过外部切面来实现日志能力:

import { Aop } from 'vona-module-a-aspect';

@Aop({ match: 'demo-student.service.student' })

class AopLog {

async update(_args: Parameters<any>, next: Function, _receiver: any) {

const timeBegin = Date.now();

const res = await next();

const timeEnd = Date.now();

console.log('time: ', timeEnd - timeBegin);

return res;

}

}

@Aop: 此装饰器用于实现外部切面

match: 用于将 Class AopLog与 Class ServiceStudent关联,ServiceStudent的 beanFullName 是demo-student.service.student

update: 在AopLog中提供与ServiceStudent同名的方法update,实现自定义逻辑即可

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/24 18:05:51

S7-1500在洁净空调控制系统中的实战应用

西门子S7-1500暖通空调制药厂洁净空调PLC程序案例&#xff0c;硬件采用西门子1500CPUET200SP接口IO模块&#xff0c;HMI采用西门子触摸屏。具体为制药厂BMS&#xff08;洁净空调自控系统&#xff09;医药洁净室程序&#xff0c;程序结构采用SCL编程。 有详细注释&#xff0c;很…

作者头像 李华
网站建设 2026/6/24 0:41:48

精通开关电源设计(第2版)资源下载

精通开关电源设计&#xff08;第2版&#xff09;资源下载 【免费下载链接】精通开关电源设计第2版资源下载 本仓库提供经典书籍《精通开关电源设计&#xff08;第2版&#xff09;》的资源下载。本书由浅入深地介绍了开关电源设计的各个方面&#xff0c;从基础的电感知识到复杂的…

作者头像 李华
网站建设 2026/6/24 20:53:13

开关电源设计实战指南:从理论到工程应用的完整解决方案

还在为复杂的开关电源设计而苦恼吗&#xff1f;面对电感参数计算、电路拓扑选择、噪声抑制等关键问题&#xff0c;你是否常常感到无从下手&#xff1f;现在&#xff0c;一本被誉为电源设计领域经典著作的《精通开关电源设计&#xff08;第2版&#xff09;》将为你提供全方位的技…

作者头像 李华
网站建设 2026/6/24 12:36:20

Harmony之路:一多适配之道——响应式布局与资源限定

Harmony之路&#xff1a;一多适配之道——响应式布局与资源限定从单设备到多设备&#xff0c;让应用在手机、平板、智慧屏上都能完美呈现在上一篇中&#xff0c;我们学习了服务卡片的开发技术&#xff0c;让应用能力突破应用边界。现在&#xff0c;我们将深入探讨HarmonyOS的一…

作者头像 李华
网站建设 2026/6/24 7:31:15

RAG系统构建必看:8种文本分块策略全解析,收藏备用!

本文详细解析了RAG系统中的8种文本分块策略&#xff0c;从基础的固定大小、递归分块到前沿的语义分块、代理分块和后置分块。每种策略各有优缺点和适用场景&#xff0c;如固定大小分块适合简单文档&#xff0c;层级分块适合结构化知识库&#xff0c;语义分块和后置分块适合高价…

作者头像 李华
网站建设 2026/6/23 22:28:35

用 Go 像写 Web 一样做桌面应用:完全离线的手机号归属地查询工具

前阵子我做了一个小工具&#xff1a;一个完全离线的手机号归属地查询桌面应用 功能本身其实并不复杂&#xff0c;但在这个过程中&#xff0c;我反而重新认识了一次 用 Go 做桌面应用&#xff0c;其实可以非常像在写一个 Web 项目。 这篇文章不打算讲手机号归属地怎么查&…

作者头像 李华