Java 通知中未识别AspectJ类型间字段

Java 通知中未识别AspectJ类型间字段,java,aop,aspectj,aspect,Java,Aop,Aspectj,Aspect,我基本上是在跟踪Account类的转账数量。 在这里阅读文档: 在幻灯片48和49中: 这些告诉我我应该可以做这样的事情: public aspect LoggingAspect { private int Account.transferCount = 0; private int Account.getTransferCount() { return transferCount; } pointcut firstTransfer(Accoun

我基本上是在跟踪Account类的转账数量。 在这里阅读文档: 在幻灯片48和49中:

这些告诉我我应该可以做这样的事情:

public aspect LoggingAspect {
    private int Account.transferCount = 0;
    private int Account.getTransferCount() {
        return transferCount;
    }

    pointcut firstTransfer(Account s, double amount):
        withincode(public void transfer (int, int, double))
            && call(public boolean withdraw(int,double))
                && target(s)
                    && args(amount);
    boolean around(Account s, double amount):
        firstTransfer(s, amount){
            s.transferCount++;     // Not recognized

            if (s.getTransferCount() == 0) {    // Not recognized
                System.out.println("50% markup");
                return s.deposit(amount*.5);
            }
            return false;
        }
}
但是,正如上面代码中所述,这些字段不会被识别为存在于方面中的类上。我做错了什么


我得到的错误是:
transferCount无法解析或不是字段

帐户
类中发生了一些事情,很遗憾,您没有在此处共享。请了解什么是一个,为什么总是提供一个是如此有价值。尤其是在AOP的上下文中,它更为重要,因为没有目标类,方面就没有多大意义。我不能在没有另一个的情况下调试一个,这就是为什么我必须发明自己的虚拟类。那实际上是你的工作

可能您正试图直接从
帐户中使用声明的私有成员。出于一个我还不明白的原因,这不起作用,因为它抛出了AspectJ编译器,并带有一个
类型Account的getTransferCount()方法不可见
或类似的错误消息。这一定是AspectJ中的一个限制或错误,我将询问维护人员,稍后在这里报告

但首先让我们重现一下你的情况:

应用程序类:

package de.scrum\u master.app;
公共类帐户{
公共无效转移(内部a、内部b、双c){
撤回(a、c);
}
公共布尔值(整数a,双c){
返回true;
}
公众存款(双倍金额){
返回true;
}
公共静态void main(字符串[]args){
账户=新账户();
转账(11、22、33.33);
账户提取(44,55.55);
转账(66,77,88.88);
账户提取(99,11.11);
//[错误]类型帐户中的getTransferCount()方法不可见
System.out.println(account.getTransferCount());
}
}
方面:

首先让我提一下,我修复了您代码中的两个错误:

  • 只有正确绑定参数,切入点才会匹配<代码>双倍金额
是两个方法参数中的第二个,而不是唯一一个。因此,您必须编写
args(*,amount)
而不是
args(amount)

  • 在检查
    s.getTransferCount()==0
    之前,您将递增
    transferCount
    ,因此
    if
    条件将永远不匹配。您需要的是
    s.getTransferCount()==1

  • package de.scrum\u master.aspect;
    导入de.scrum_master.app.Account;
    公共方面{
    私有int Account.transferCount=0;
    私有int帐户。getTransferCount(){
    返回转移计数;
    }
    切入点首次转账(账户,双倍金额):
    withincode(公共无效传输(整数、整数、双精度))&&
    调用(公共布尔值撤消(整数,双精度))&&
    目标(s)&&
    args(*,金额);
    布尔值(帐户,双倍金额):首次转账(帐户,金额){
    s、 transferCount++;
    如果(s.getTransferCount()==1){
    系统输出打印项次(“50%加价”);
    退还押金(金额*.5);
    }
    返回false;
    }
    }
    
    现在在Eclipse中,我看到了应用程序类中的编译错误,由于编译失败,导致了方面本身的后续问题。只要您注释掉
    main
    方法的最后一行,它就会工作。(可能您必须重新保存外观或重新编译项目,以使曲线消失。)

    实际上,最简单的方法是将
    getTransferCount()
    设置为公共而不是私有。getter通常是公共的,然后您还可以再次使用
    main
    方法中的方法,程序输出将变成:

    50%加价
    2.
    
    顺便说一句,在方面内部,您不需要使用
    getTransferCount()
    。就像上面的一行一样,您可以直接访问该字段


    更新:我答应过你一个问题的答案,为什么目标类不能通过ITD访问声明为
    private
    的字段和方法:因为它们对于方面本身是私有的!这个答案来自AspectJ维护人员本人,请阅读。

    更新:我的答案现在解释了从目标类访问通过ITD声明的私有字段/方法时出现的编译器错误。