【问题标题】:AspectJ - change value of method parameterAspectJ - 改变方法参数的值
【发布时间】:2017-08-14 11:55:01
【问题描述】:

我想要这样的东西:

public void doSomething(@ReplaceFooBar String myString) {
    //...
}

ReplaceFooBar 是我的自定义注释,它应该采用myString 的值,并在方法开始执行之前执行带有“bar”的“foo”的replaceAll,以便它使用新的字符串值执行。因此,如果使用参数“I'm at the foo”调用该方法。它实际上应该以“我在酒吧”来执行。

我不知道如何进行这项工作。我一直在摆弄这个有一段时间了。假设我最后一次结束了这一点:

@Documented
@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ReplaceFooBar {
}

还有……

@Aspect
public aspect ReplaceFooBarAspect {
    @Before("@annotation(ReplaceFooBar)")
    public String replaceFooBar(String value) {
        if (value == null) {
            return null;
        }
        return value.replaceAll("foo", "bar");
    }
}

我做错了什么?

我的代码没有编译,我遇到了这样的错误。

Error:(6, 0) ajc: Duplicate annotation @Aspect
Error:(7, 0) ajc: aspects cannot have @Aspect annotation
Error:(10, 0) ajc: This advice must return void
Error:(10, 0) ajc: formal unbound in pointcut

我不知道这些方面究竟是如何工作的,如何让它按照我想要的方式工作。

【问题讨论】:

  • 嗯...它甚至没有编译。我认为这对于知道如何帮助我的人来说是显而易见的。以下是错误:Error:(6, 0) ajc: Duplicate annotation @Aspect Error:(7, 0) ajc: aspects cannot have @Aspect annotation Error:(10, 0) ajc: This advice must return void Error:(10, 0) ajc: formal unbound in pointcut
  • 我真的不知道为什么这很重要。对于任何了解这些方面的人来说,应该非常清楚它不能编译。通过添加它,我只是用不必要的数据使我的问题变得混乱。但是好吧,如果它能让你开心的话。
  • 好吧,如果我知道如何编写代码,我真的很乐意为您提供可验证的代码。我花了几个小时试图让它今天工作但没有成功。所以我想也许这里有人知道答案,这对他/她来说是显而易见的,特别是因为这个例子非常简单,最后从我的角度来看。因此,与其花更多时间在上面,有人可以直接帮助我花 5 分钟的时间。不幸的是,我现在没有时间阅读 AspectJ 教程并自己学习所有细节。

标签: java annotations aspectj


【解决方案1】:

要执行具有不同参数的方法,您应该使用@Around 建议并在代码中手动替换参数。

例如:

@Around("execution(* *(.., @aspectjtest.ReplaceFooBar (*), ..))")
public Object replaceFooBar(ProceedingJoinPoint pjp) throws Throwable {
    //get original args
    Object[] args = pjp.getArgs();

    //get all annotations for arguments
    MethodSignature signature = (MethodSignature) pjp.getSignature();
    String methodName = signature.getMethod().getName();
    Class<?>[] parameterTypes = signature.getMethod().getParameterTypes();
    Annotation[][] annotations;
    try {
        annotations = pjp.getTarget().getClass().
                getMethod(methodName, parameterTypes).getParameterAnnotations();
    } catch (Exception e) {
        throw new SoftException(e);
    }

    //Find annotated argument
    for (int i = 0; i < args.length; i++) {
        for (Annotation annotation : annotations[i]) {
            if (annotation.annotationType() == ReplaceFooBar.class) {
                Object raw = args[i];
                if (raw instanceof String) {
                    // and replace it with a new value
                    args[i] = ((String) raw).replaceAll("foo", "bar");
                }
            }
        }
    }
    //execute original method with new args
    return pjp.proceed(args);
}

【讨论】:

  • 是否可以更改参数的数据类型?例如,我们接受字符串,然后将其数据类型更改为 int?该方法还会接受它吗?
  • 我想你会得到 NoSuchMethodError ,因为参数的类型是方法签名的一部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-27
相关资源
最近更新 更多