gpt4 book ai didi

aspectj - 如何修改未知数量的方法参数与方面的方面

转载 作者:行者123 更新时间:2023-12-04 08:57:38 29 4
gpt4 key购买 nike

我想创建一个注释,它使用环绕方面来使用该注释清理参数。
例如,一个方法可能如下所示:

public void setName(@Scrubbed String name) { ... }
也许
public void setFullName(@Scrubbed String firstName, @Scrubbed String lastName) { ... }
我想做的是沿着这些思路:
Object around(String arg) : call(* *(.., @Scrubbed (String), ..)) {
return proceed(this.scrubString(arg));
}
但是,我想以任何顺序处理任意数量的参数。
我有什么工作,但看起来像一个黑客是这样的:
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 而不是proceed()。
我希望能够访问 ProceedingJoinPoint 并调用它提供的proceed(Ojbect[] args) 方法,但我不知道如何使用 native aspectj 语法来做到这一点。
有任何想法吗。我想我可以使用注解@AJ aspectj 语法,但我们的其他方面都使用 native 语法。

最佳答案

非常抱歉,我无法为您提供原生 AspectJ 语法的优雅解决方案,因为我更喜欢它而不是基于注释的语法。但这是在@AspectJ 语法中您想要实现的目标更容易实现的罕见情况之一。
就任意位置和数字中的参数注释而言,您需要按照您已经建议的方式使用反射。传统的切入点和参数绑定(bind)语法无法处理这种关于方法签名的不确定性。
但是继续使用 getArgs() 的修改版本@AspectJ 语法中确实可以使用参数数组。开始了:
标记注释:

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 {}
目标类+驱动应用程序:
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");
}
}
方面:
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]", "#");
}
}
控制台日志:
name = Alb#rt #inst#in
firstName = Alb#rt, lastName = #inst#in

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

I supposed I could use annotation @AJ aspectj syntax, but the rest of our aspects are using native syntax.


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

关于aspectj - 如何修改未知数量的方法参数与方面的方面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63732442/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com