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

AspectJ成员引入构建失败,@Tracking类方法注入异常求助

问题分析与解决方案

你遇到的核心问题是:未通过**Inter-Type Declaration(ITD,类型间声明)**语法将方法和状态正确注入到目标类实例中。原切面中的go()只是切面自身的方法,不会被自动注入到带@Tracking注解的类;而直接指定Test.go()时,方法内的return set会试图访问Test类自身不存在的成员,导致运行时错误。

修正后的完整实现

1. 确保@Tracking注解为运行时可见

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Tracking {
}

2. 标记目标POJO

@Tracking
class Test {
  private int i;
  void setI(int i) {
    this.i = i;
  }
}

3. 修正后的切面代码

import java.util.HashSet;
import java.util.Set;

public aspect TrackingAspect perthis(within(@Tracking *)) {
  // 每个切面实例对应一个目标对象的方法名集合(与目标实例一一绑定)
  private Set<String> set = new HashSet<>();

  // 仅拦截带@Tracking注解类的setter方法
  pointcut setterMethod() : execution(void set*(..)) && within(@Tracking *);

  // 拦截setter调用,记录方法名
  after() returning() : setterMethod() {
    set.add(thisJoinPoint.getSignature().getName());
    System.out.println("当前记录的方法:" + set);
  }

  // 给所有带@Tracking注解的类注入go()方法
  public Set<String> @Tracking *.go() {
    // 获取当前对象对应的切面实例,返回绑定的集合
    return TrackingAspect.aspectOf(this);
  }
}

关键说明

  1. ITD语法注入方法:通过public Set<String> @Tracking *.go()语法,将方法注入到所有带@Tracking注解的类中,而不是局限于单个类。
  2. 关联切面与目标实例:perthis(within(@Tracking *))确保每个目标类实例对应一个切面实例,切面内的set集合与目标实例一一绑定。
  3. 正确获取关联状态:注入的go()方法通过TrackingAspect.aspectOf(this)获取当前对象对应的切面实例,返回其持有的set集合,避免访问目标类不存在的成员。

测试示例

public class Main {
  public static void main(String[] args) {
    Test test = new Test();
    test.setI(1);
    test.setI(2);
    // 调用注入的go()方法,输出 [setI]
    System.out.println("最终记录的方法集合:" + test.go());
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 21:31:01