如何在Dart中让指定函数在类的所有方法执行前运行?
在Dart中实现方法执行前自动调用特定函数的方案
Dart没有原生的AOP(面向切面编程)支持,但可以通过Mixin、代理模式或注解生成代码的方式,避免手动在每个方法里重复调用前置函数。以下是几种实用方案:
方案1:Mixin封装前置逻辑
用Mixin复用前置执行逻辑,通过模板方法统一处理前置函数调用和业务代码执行:
mixin RunBeforeMixin { // 定义需要前置执行的函数 void shouldRunFirst() { print("执行前置逻辑"); } // 模板方法:先跑前置函数,再执行传入的业务逻辑 void runWithPreLogic(void Function() business) { shouldRunFirst(); business(); } } class A with RunBeforeMixin { void functionA() { runWithPreLogic(() { print("执行functionA的业务代码"); }); } void functionB() { runWithPreLogic(() { print("执行functionB的业务代码"); }); } }
调用functionA或functionB时,会自动先执行shouldRunFirst,再运行业务代码。
方案2:手动代理类
如果不想修改原有类的结构,可以创建代理类,所有方法调用都通过代理转发,代理类负责先执行前置逻辑:
// 原有业务类,无需修改 class A { void functionA() => print("执行functionA的业务代码"); void functionB() => print("执行functionB的业务代码"); } // 代理类,拦截方法调用 class AProxy { final A _original; AProxy(this._original); void shouldRunFirst() => print("执行前置逻辑"); void functionA() { shouldRunFirst(); _original.functionA(); } void functionB() { shouldRunFirst(); _original.functionB(); } } // 使用示例 void main() { final proxy = AProxy(A()); proxy.functionA(); // 先执行前置逻辑,再调用A的functionA }
这种方式的优势是原业务类完全不受影响,但需要为每个方法编写代理方法。
方案3:注解+代码生成(适合大量方法场景)
如果类中有大量方法需要添加前置逻辑,手动编写重复代码效率低,可以用注解结合build_runner自动生成代码:
- 添加依赖到
pubspec.yaml:
dependencies: meta: ^1.9.0 dev_dependencies: build_runner: ^2.4.4 source_gen: ^1.3.2
- 定义注解:
import 'package:meta/meta.dart'; @Target({TargetKind.method}) class RunBefore extends Annotation { const RunBefore(); }
- 编写代码生成器(简化版):
import 'package:build/build.dart'; import 'package:source_gen/source_gen.dart'; import 'package:meta/meta.dart'; class RunBeforeGenerator extends GeneratorForAnnotation<RunBefore> { @override String generateForAnnotatedElement(Element element, ConstantReader annotation, BuildStep buildStep) { if (element is! MethodElement) return ''; final className = element.enclosingElement.name; final methodName = element.name; // 生成带前置逻辑的扩展方法 return ''' extension ${className}PreLogicExtension on $className { void ${methodName}_withPre() { shouldRunFirst(); $methodName(); } } '''; } }
- 在业务类中标记需要添加前置逻辑的方法:
class A { void shouldRunFirst() => print("执行前置逻辑"); @RunBefore() void functionA() => print("执行functionA的业务代码"); @RunBefore() void functionB() => print("执行functionB的业务代码"); }
- 运行代码生成命令:
dart run build_runner build
生成后就可以通过a.functionA_withPre()来触发前置逻辑+原方法的执行,也可以调整生成器逻辑直接覆盖原方法(需注意命名冲突)。
注意:Flutter项目禁用
dart:mirrors反射,因此反射方案不适用,上述三种是更稳妥的选择。
内容的提问来源于stack exchange,提问作者Yuki
相关产品推荐
相关产品推荐

