我想要创建一个注释,该注释使用FoundA方面来清除该注释中的参数。
例如,方法可能如下所示:
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而不是()。
我希望能够访问ProceedingJoinPoint并调用它提供的继续(Ojbect[] args)方法,但我不知道如何使用本机aspectj语法。
任何想法。我以为我可以使用注释@ aspectj语法,但我们的其他方面使用的是本机语法。
发布于 2020-09-04 05:35:44
非常抱歉,我无法在本机AspectJ语法中为您提供一个优雅的解决方案,因为比起基于注释的语法,我更喜欢它。但是,这是您希望在@AspectJ语法中更容易实现的罕见情况之一。
对于任意位置和数字中的参数注释,您需要按照建议的方式使用反射。这种与方法签名有关的不确定性不能通过传统的切入点和参数绑定语法来处理。
但是,在@AspectJ语法中继续使用修改后的getArgs()参数数组确实是可能的。我们开始:
标记注释:
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更新:--我刚刚看到您已经建议了这种方法:
-我以为我可以使用注释@ aspectj语法,但我们的其他方面使用的是本机语法。
这可能是一个表面上的缺陷,但您没有理由不能混合这两种语法类型,只要您不将它们混合在同一方面。(即使后者在许多情况下也有效,但在某些情况下却行不通。)
https://stackoverflow.com/questions/63732442
复制相似问题