Aspectj 可选参数绑定
Aspectj optional parameter binding
我希望 Aspectj 使用 args 绑定我的方法参数。
像这样:
@Before("@annotation(authorized) && args(java.util.String)")
public void authorize(JoinPoint joinPoint, Authorized authorized, String str)
但是,我不能指望字符串参数存在。我希望将建议应用于使用该注释的所有方法,而不仅仅是带有 String 参数的方法。
如果建议的方法没有 String 参数,我希望 str
填充空值。
这可能吗?或者是使用 joinPoint.getArgs()
的唯一选项?
您可以使用 getArgs(),另一种方法是创建多个委托给您要执行的功能的建议:
@Before("@annotation(authorized) && execution(* *())") // no string
public void authorize(JoinPoint joinPoint, Authorized authorized) {
helper(joinPoint,authorized,null);
}
// 1 argument, which is the string
@Before("@annotation(authorized) && execution(* *(..)) && args(str)")
public void authorize(JoinPoint joinPoint, Authorized authorized, String str) {
helper(joinPoint,authorized,str);
}
请注意,我还包括一个执行切入点元素。包括这一点可能很重要。否则,如果使用纯 AspectJ 编译,没有它的切入点可能会同时匹配方法的调用和执行连接点,运行 建议两次。
I have an answer to the question you asked in the comment to Andy's answer:
Would it be possible to advice methods with unknown amount of arguments, but not ending with an argument of a specific type?
package de.scrum_master.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Authorized {}
package de.scrum_master.app;
public class Application {
@Authorized static void bla(String string, int i, int j) {}
@Authorized static void baz(String string, int i, Integer integer) {}
@Authorized static void zot(String string) {}
@Authorized static void bar(Integer integer) {}
@Authorized static void foo() {}
public static void main(String[] args) {
foo();
bar(new Integer(11));
zot("xxx");
baz("yyy", 123, new Integer(22));
bla("zzz", 123, 456);
}
}
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import de.scrum_master.app.Authorized;
@Aspect
public class MyAspect {
@Before("@annotation(authorized) && execution(* *(..)) && !execution(* *(.., Integer))")
public void authorize(JoinPoint joinPoint, Authorized authorized) {
System.out.println(joinPoint);
}
}
Console output:
execution(void de.scrum_master.app.Application.foo())
execution(void de.scrum_master.app.Application.zot(String))
execution(void de.scrum_master.app.Application.bla(String, int, int))
As you can see, the two methods baz
and bar
not ending with a certain type - Integer
in this example - are excluded from matching.
我希望 Aspectj 使用 args 绑定我的方法参数。
像这样:
@Before("@annotation(authorized) && args(java.util.String)")
public void authorize(JoinPoint joinPoint, Authorized authorized, String str)
但是,我不能指望字符串参数存在。我希望将建议应用于使用该注释的所有方法,而不仅仅是带有 String 参数的方法。
如果建议的方法没有 String 参数,我希望 str
填充空值。
这可能吗?或者是使用 joinPoint.getArgs()
的唯一选项?
您可以使用 getArgs(),另一种方法是创建多个委托给您要执行的功能的建议:
@Before("@annotation(authorized) && execution(* *())") // no string
public void authorize(JoinPoint joinPoint, Authorized authorized) {
helper(joinPoint,authorized,null);
}
// 1 argument, which is the string
@Before("@annotation(authorized) && execution(* *(..)) && args(str)")
public void authorize(JoinPoint joinPoint, Authorized authorized, String str) {
helper(joinPoint,authorized,str);
}
请注意,我还包括一个执行切入点元素。包括这一点可能很重要。否则,如果使用纯 AspectJ 编译,没有它的切入点可能会同时匹配方法的调用和执行连接点,运行 建议两次。
I have an answer to the question you asked in the comment to Andy's answer:
Would it be possible to advice methods with unknown amount of arguments, but not ending with an argument of a specific type?
package de.scrum_master.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Authorized {}
package de.scrum_master.app;
public class Application {
@Authorized static void bla(String string, int i, int j) {}
@Authorized static void baz(String string, int i, Integer integer) {}
@Authorized static void zot(String string) {}
@Authorized static void bar(Integer integer) {}
@Authorized static void foo() {}
public static void main(String[] args) {
foo();
bar(new Integer(11));
zot("xxx");
baz("yyy", 123, new Integer(22));
bla("zzz", 123, 456);
}
}
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import de.scrum_master.app.Authorized;
@Aspect
public class MyAspect {
@Before("@annotation(authorized) && execution(* *(..)) && !execution(* *(.., Integer))")
public void authorize(JoinPoint joinPoint, Authorized authorized) {
System.out.println(joinPoint);
}
}
Console output:
execution(void de.scrum_master.app.Application.foo())
execution(void de.scrum_master.app.Application.zot(String))
execution(void de.scrum_master.app.Application.bla(String, int, int))
As you can see, the two methods baz
and bar
not ending with a certain type - Integer
in this example - are excluded from matching.