我使用AspectJ来拦截一个名为Request(String, String)
的方法。为此,我使用自己的指定(标记)注释。这就是班级的样子:
Class myclass {
public void Request(@Intercept String t, String u) {
// ...
}
}
拦截@Intercept
注释的方面:
@Aspect
class someAspect {
@Intercept
@Around("execution(public * * (@Interceptor (*), ..))")
public void capture(ProceedingJoinPoint pjp) {
// ...
}
}
但是,我的方面是根据带注释的参数进行拦截。但我希望方面拦截方法请求对参数t包含的特定值。
例如,如果t == "t1"
,则必须拦截该方法,否则不会。
我想知道是否可以在AspectJ(与Spring AOP结合使用)中执行此操作。
答案 0 :(得分:0)
实际上你的代码存在一些问题(我只是重新格式化它,所以它至少是可读的):
MyClass
或SomeAspect
,而不是myclass
或someAspect
。request
而不是Request
。@Intercept
和@Interceptor
。从现在开始,我将假设实际上我们只处理了一个名为@Intercept
,好吗?@Intercept
注释您方面的建议,但我想这不是故意的,是吗?如果拦截建议拦截自己,它可能导致另一个切入点的无限递归...... 至于你的实际问题,那么答案是:在切入点中排序(但不是静态)(因为参数仅在runime期间确定),但是在运行时也是动态的。您有两种选择:
选项A:if
- 建议代码中的else
package de.scrum_master.app;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Intercept {}
package de.scrum_master.app;
public class Application {
public static void one(@Intercept String string) {}
public static void two(String string, String string2) {}
public static void three(@Intercept String string, int i, int j) {}
public static void main(String[] args) {
one("foo");
two("foo", "bar");
three("foo", 11, 22);
one("bingo");
two("bingo", "bongo");
three("bingo", 33, 44);
}
}
package de.scrum_master.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class InterceptorAspect {
@Pointcut("execution(public * *(@de.scrum_master.app.Intercept (*), ..)) && args(text, ..)")
public static void normalPointcut(String text) {}
@Around("normalPointcut(text)")
public Object capture(ProceedingJoinPoint thisJoinPoint, String text) {
if (text != "bingo")
return thisJoinPoint.proceed();
System.out.println(thisJoinPoint);
for (Object arg : thisJoinPoint.getArgs())
System.out.println(" " + arg);
// Do something before calling the original method
Object result = thisJoinPoint.proceed();
// Do something after calling the original method
return result;
}
}
选项B:使用if()
切入点
if()
pointcut是一个静态方法,它根据您要测试的动态条件返回一个布尔值。重构的方面看起来像这样:
package de.scrum_master.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class InterceptorAspect {
@Pointcut("if() && execution(public * *(@de.scrum_master.app.Intercept (*), ..)) && args(text, ..)")
public static boolean conditionalPointcut(String text) {
return text != "bingo";
}
@Around("conditionalPointcut(text)")
public Object capture(ProceedingJoinPoint thisJoinPoint, String text) {
System.out.println(thisJoinPoint);
for (Object arg : thisJoinPoint.getArgs())
System.out.println(" " + arg);
// Do something before calling the original method
Object result = thisJoinPoint.proceed();
// Do something after calling the original method
return result;
}
}
正如您所看到的,基于参数的动态条件已移至切入点,该切入点不再是具有空体的void
方法,而是返回参数检查结果的boolean
方法。此外,切入点表达式以if() &&
表达式为前缀。
控制台日志:
两个方面变体的控制台输出完全相同:
execution(void de.scrum_master.app.Application.one(String))
foo
execution(void de.scrum_master.app.Application.three(String, int, int))
foo
11
22