AspectJ - 方法参数的更改值
AspectJ - change value of method parameter
我想要这样的东西:
public void doSomething(@ReplaceFooBar String myString) {
//...
}
ReplaceFooBar
是我的自定义注释,它应该采用 myString
的值,并在方法之前执行 "foo" 的 replaceAll
和 "bar"开始执行,以便它使用新的字符串值执行。因此,如果使用参数 "I'm at the foo." 调用该方法,它实际上应该使用 "I'm at the bar."
执行
我不知道该怎么做。我已经摆弄了一段时间了。假设我最后一次结束于此:
@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
我不知道这些方面究竟是如何工作的,如何让它按照我想要的方式工作。
要使用不同的参数执行方法,您应该使用 @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);
}
我想要这样的东西:
public void doSomething(@ReplaceFooBar String myString) {
//...
}
ReplaceFooBar
是我的自定义注释,它应该采用 myString
的值,并在方法之前执行 "foo" 的 replaceAll
和 "bar"开始执行,以便它使用新的字符串值执行。因此,如果使用参数 "I'm at the foo." 调用该方法,它实际上应该使用 "I'm at the bar."
我不知道该怎么做。我已经摆弄了一段时间了。假设我最后一次结束于此:
@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
我不知道这些方面究竟是如何工作的,如何让它按照我想要的方式工作。
要使用不同的参数执行方法,您应该使用 @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);
}