首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用aspectj在方面修改未知数量的方法args

如何用aspectj在方面修改未知数量的方法args
EN

Stack Overflow用户
提问于 2020-09-03 22:25:05
回答 1查看 137关注 0票数 2

我想要创建一个注释,该注释使用FoundA方面来清除该注释中的参数。

例如,方法可能如下所示:

代码语言:javascript
运行
复制
public void setName(@Scrubbed String name) { ... }

或者也许

代码语言:javascript
运行
复制
public void setFullName(@Scrubbed String firstName, @Scrubbed String lastName) { ... }

我想做的是以下几点:

代码语言:javascript
运行
复制
Object around(String arg) : call(* *(.., @Scrubbed (String), ..)) {
    return proceed(this.scrubString(arg));
}

但是,我想按任何顺序处理任意数量的参数。我所做的工作,但它似乎是一个黑客:

代码语言:javascript
运行
复制
Object around() : call(public * *(.., @Scrubbed (String), ..)) {
    Method method = MethodSignature.class.cast(thisJoinPoint.getSignature()).getMethod();
    Object[] args = thisJoinPoint.getArgs();
    Annotation[][] parameterAnnotations = method.getParameterAnnotations();
    for (int argIndex = 0; argIndex < args.length; argIndex++) {
        for (Annotation paramAnnotation : parameterAnnotations[argIndex]) {
            if (!(paramAnnotation instanceof Scrubbed)) {
                continue;
            }
            args[argIndex] = this.scrubString((String)args[argIndex]);
        }
    }
    try {
        return method.invoke(thisJoinPoint.getTarget(), args);
    } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        e.printStackTrace();
    }
    return null;
}

我基本上是使用joinPoint来访问反射信息,最终使用的是method.invoke而不是()。

我希望能够访问ProceedingJoinPoint并调用它提供的继续(Ojbect[] args)方法,但我不知道如何使用本机aspectj语法。

任何想法。我以为我可以使用注释@ aspectj语法,但我们的其他方面使用的是本机语法。

EN

Stack Overflow用户

回答已采纳

发布于 2020-09-04 05:35:44

非常抱歉,我无法在本机AspectJ语法中为您提供一个优雅的解决方案,因为比起基于注释的语法,我更喜欢它。但是,这是您希望在@AspectJ语法中更容易实现的罕见情况之一。

对于任意位置和数字中的参数注释,您需要按照建议的方式使用反射。这种与方法签名有关的不确定性不能通过传统的切入点和参数绑定语法来处理。

但是,在@AspectJ语法中继续使用修改后的getArgs()参数数组确实是可能的。我们开始:

标记注释:

代码语言:javascript
运行
复制
package de.scrum_master.app;

import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Retention(RUNTIME)
@Target(PARAMETER)
public @interface Scrubbed {}

目标类+驱动程序应用程序:

代码语言:javascript
运行
复制
package de.scrum_master.app;

public class Application {
  public void setName(@Scrubbed String name) {
    System.out.println("name = " + name);
  }

  public void setFullName(@Scrubbed String firstName, @Scrubbed String lastName) {
    System.out.println("firstName = " + firstName + ", lastName = " + lastName);
  }

  public static void main(String[] args) {
    Application application = new Application();
    application.setName("Albert Einstein");
    application.setFullName("Albert", "Einstein");
  }
}

方面:

代码语言:javascript
运行
复制
package de.scrum_master.aspect;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;

import de.scrum_master.app.Scrubbed;

@Aspect
public class StringScrubberAspect {
  @Around("call(public * *(.., @de.scrum_master.app.Scrubbed (String), ..))")
  public Object scrubStringAdvice(ProceedingJoinPoint thisJoinPoint) throws Throwable {
    Method method = MethodSignature.class.cast(thisJoinPoint.getSignature()).getMethod();
    Object[] args = thisJoinPoint.getArgs();
    Annotation[][] parameterAnnotations = method.getParameterAnnotations();
    for (int argIndex = 0; argIndex < args.length; argIndex++) {
      for (Annotation paramAnnotation : parameterAnnotations[argIndex]) {
        if (paramAnnotation instanceof Scrubbed)
          args[argIndex] = scrubString((String) args[argIndex]);
      }
    }
    return thisJoinPoint.proceed(args);
  }

  private String scrubString(String string) {
    return string.replaceAll("[Ee]", "#");
  }
}

控制台日志:

代码语言:javascript
运行
复制
name = Alb#rt #inst#in
firstName = Alb#rt, lastName = #inst#in

更新:--我刚刚看到您已经建议了这种方法:

-我以为我可以使用注释@ aspectj语法,但我们的其他方面使用的是本机语法。

这可能是一个表面上的缺陷,但您没有理由不能混合这两种语法类型,只要您不将它们混合在同一方面。(即使后者在许多情况下也有效,但在某些情况下却行不通。)

票数 2
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63732442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档