You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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自动生成代码:

  1. 添加依赖到pubspec.yaml:
dependencies:
  meta: ^1.9.0

dev_dependencies:
  build_runner: ^2.4.4
  source_gen: ^1.3.2
  1. 定义注解:
import 'package:meta/meta.dart';

@Target({TargetKind.method})
class RunBefore extends Annotation {
  const RunBefore();
}
  1. 编写代码生成器(简化版):
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();
  }
}
''';
  }
}
  1. 在业务类中标记需要添加前置逻辑的方法:
class A {
  void shouldRunFirst() => print("执行前置逻辑");

  @RunBefore()
  void functionA() => print("执行functionA的业务代码");

  @RunBefore()
  void functionB() => print("执行functionB的业务代码");
}
  1. 运行代码生成命令:
dart run build_runner build

生成后就可以通过a.functionA_withPre()来触发前置逻辑+原方法的执行,也可以调整生成器逻辑直接覆盖原方法(需注意命名冲突)。

注意:Flutter项目禁用dart:mirrors反射,因此反射方案不适用,上述三种是更稳妥的选择。

内容的提问来源于stack exchange,提问作者Yuki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 22:12:17