0

我有许多类覆盖等于对象比较。对于每个 equals 实现,它使用区分大小写的 String .equals。我想知道是否可以使用 AspectJ 在每种方法中简单地将 .equals 替换为 .equalsIgnoreCase ?

或者,如果上述情况不可行,我们是否可以使用 AspectJ 拦截该类以使用我自己的 String .equals 实现?(不改变方法实现)

4

1 回答 1

1

您希望 String.equals(Object anObject) 方法在包中每次出现时都重新路由到 equalsIgnoreCase(String) ,对吗?

它的切入点需要call(boolean equals(Object))在你的包 ( within(your.packages.*)) 中拦截对 equals ( ) 的调用,并提供目标 ( target(sourceString)) 和参数 ( args(compareString)),所以它应该如下所示:

@Pointcut("call(boolean equals(Object)) && args(compareString) && target(sourceString) && within(your.packages.*)")
protected void equalsPointcut(final Object compareString, final String sourceString) {}

使用该切入点的建议必须是一个环绕建议,它会跳过对 equals 的调用,而是自己调用 equalsIgnoreCase:

@Around("equalsPointcut(compareString, sourceString)")
public Object around(final ProceedingJoinPoint joinPoint, final Object compareString, final String sourceString)
        throws Throwable {
    System.out.println("Aspect!");
    return sourceString.equalsIgnoreCase(compareString != null ? compareString.toString() : null);
}

sysout 只是用来检查切面是否被实际使用,当然应该在实际用例中被删除。

我的测试如下所示:

public static void main(final String[] args) {
    String a = "Blaaaa";
    String b = "BLAAAA";

    System.out.println(a.equals(b));
    Object c = new Object();
    System.out.println(c.equals(b));
}

它产生输出:

Aspect!
true
false

注意 a.equals(b) 被重新路由到 equalsIgnoreCase (因为它的目标是一个字符串),但 c.equals(b) 不是(因为它的目标是一个对象!)。

我希望这回答了你的问题。快乐编码!;)

于 2013-08-27T12:52:40.347 回答