我正在使用AeyJ拦截一个名为Request(String, String)
的方法。为此,我使用了我自己指定的(标记)注释。这就是类的样子:
Class myclass {
public void Request(@Intercept String t, String u) {
// ...
}
}
截取截取注释的方面:
@Aspect
class someAspect {
@Intercept
@Around("execution(public * * (@Interceptor (*), ..))")
public void capture(ProceedingJoinPoint pjp) {
// ...
}
}
然而,我的方面是基于带注释的参数进行拦截。但我希望方面能够拦截参数t包含的特定值的方法请求。
例如,如果t==“t1”,则必须截取该方法,否则不能截取。
我想知道是否可以在AeyJ(与Spring AOP结合使用)中做到这一点。
实际上,您的代码存在一些问题(我只是重新格式化了它,因此它至少是可读的):
MyClass
或某些方面
而不是myclass
或某些方面
。Request
而不是Request
。@Intercept
和@Interceptor
。从现在开始,我将假设实际上我们正在处理的只是一个名为@Intercept
的注释,好吗?@Intercept
注释了方面的建议,但我想这不是有意的,是吗?如果拦截建议正在拦截自己,它可能会导致另一个切入点中的无限递归...至于您的实际问题,那么答案是:某种程度上,但不是静态地在切入点内(因为参数仅在运行时确定),而是动态地,也在运行时。您有两种选择:
选项A:if
-其他
在建议代码中
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()切入点是一种静态方法,根据要测试的动态条件返回布尔值。重构方面如下所示:
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;
}
}
如您所见,动态的、基于参数的条件已移入切入点,它不再是具有空体的val
方法,而是返回参数检查结果的布尔
方法。此外,切入点表达式前面有一个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
我最近用aspectJ和spring-aop添加了AOP到我现有的spring项目中。目标是实际截获控制器调用以修改它们发回的响应,以便将一些值绑定到此响应,我不想手动添加到每个控制器中,例如最终用户使用的实际令牌的到期日期(无论如何我都无法在控制器中显示它)。实际上,在开始单元测试之前,我一直设法让它工作: 在我的单元测试中,我使用java中的反射特性直接调用我的控制器方法,然后复制通常的过程(
我试图让aspectj拦截带注释的方法: 我删除了!为了简洁起见,在(InterceptMeAspect)内,但它并没有拦截太多。如果我删除注释约束(在(@InterceptMe*)内),它可以工作,但会拦截所有内容,这会造成一个大问题。 输出字节码似乎有完整的注释,所以我希望注释标准匹配。我正在或试图进行编译时编织。这很重要,因为我有另一个方面确实使用上面相同的方法工作。我怀疑该方面正在搞乱这个
我正在使用Spring并试图用AspectJ编写示例应用程序。我需要学习如何拦截静态方法调用。在我的示例中,我尝试截取main方法,如下所示: Spring配置文件: 主要方法: 协会本身: 但是当我运行应用程序时,唯一的字符串正在打印。
我正在尝试使用来做同样的事情,现在我使用哪个注释来捕获相关的对象,切入点表达式应该是什么?我尝试了,但这是一个void方法,如何捕获该方法的参数?我是AOP的初学者,所以如果这个问题太琐碎,请原谅。 解决方案:使用spring AOP获取方法参数?
我的情况如下:我有一个loggingapect,其中有几个切入点与我的主应用程序中的特定方法执行相匹配。相应的建议机构基本上看起来都很相似,导致大量代码重复: 不过也有一些变化。有时是切入点 经常发生的事情是我手动告诉记录器 在打印第一条消息后,即在调用procedue()之前,增加缩进级别,并且 在打印最终消息之前(如果打印了任何消息),即直接在返回后降低缩进级别 我的想法是,我想用一个切入点编