AspectJ:切入点中的参数

时间:2008-11-05 16:21:28

标签: aspectj

我正在使用AspectJ来建议所有具有所选类参数的公共方法。我尝试了以下方法:

pointcut permissionCheckMethods(Session sess) : 
    (execution(public * *(.., Session)) && args(*, sess));

对于至少包含2个参数的方法,这非常有效:

public void delete(Object item, Session currentSession);

但它不适用于以下方法:

public List listAll(Session currentSession);

如何更改我的切入点以建议两种方法执行?换句话说:我希望“..”通配符代表“零个或多个参数”,但看起来它意味着“一个或多个”...

5 个答案:

答案 0 :(得分:8)

哦,好吧......我用这个讨厌的伎俩解决了这个问题。仍在等待有人出现“官方”切入点定义。

pointcut permissionCheckMethods(EhealthSession eheSess) : 
    (execution(public * *(.., EhealthSession)) && args(*, eheSess))
    && !within(it.___.security.PermissionsCheck);

pointcut permissionCheckMethods2(EhealthSession eheSess) : 
    (execution(public * *(EhealthSession)) && args(eheSess))
    && !within(it.___.security.PermissionsCheck)
    && !within(it.___.app.impl.EhealthApplicationImpl);

before(EhealthSession eheSess) throws AuthorizationException : permissionCheckMethods(eheSess)
{
    Signature sig = thisJoinPointStaticPart.getSignature(); 
    check(eheSess, sig);
}

before(EhealthSession eheSess) throws AuthorizationException : permissionCheckMethods2(eheSess)
{
    Signature sig = thisJoinPointStaticPart.getSignature(); 
    check(eheSess, sig);
}

答案 1 :(得分:4)

怎么样:

pointcut permissionCheckMethods(Session sess) : 
(execution(public * *(..)) && args(.., sess));

我想如果last(或only)参数是Session类型,这将匹配。通过交换args的位置,您也可以先匹配或仅匹配。但我不知道是否可以匹配任意位置。

答案 2 :(得分:3)

我无法为您扩展AspectJ语法,但我可以提供一种解决方法。但首先让我解释为什么在切入点中使用args定义无法做到你想做的事情:因为如果你在方法签名中的任何地方匹配你的EhealthSession参数,那么AspectJ应该如何处理签名包含该类的多个参数的情况? eheSess的含义不明确。

现在解决方法:它可能会更慢 - 多少取决于您的环境,只需测试它 - 但您可以让切入点匹配所有可能的方法,无论其参数列表如何,然后让建议找到您需要的参数检查参数列表:

pointcut permissionCheckMethods() : execution(public * *(..));

before() throws AuthorizationException : permissionCheckMethods() {
    for (Object arg : thisJoinPoint.getArgs()) {
        if (arg instanceof EhealthSession)
            check(arg, thisJoinPointStaticPart.getSignature());
    }
}

P.S。:也许您可以通过within(SomeBaseClass+)within(*Postfix)within(com.company.package..*)缩小焦点,以免将建议应用于整个世界。

答案 3 :(得分:3)

您必须在结尾和开头使用..(双点),如下所示:

pointcut permissionCheckMethods(Session sess) : 
    (execution(public * *(.., Session , ..)) );

同样摆脱&& args(*, sess),因为这意味着你希望只捕获第一个参数的任何类型的方法,但sess作为第二个参数,并且不超过2个参数...

答案 4 :(得分:0)

@Before(value = "execution(public * *(.., org.springframework.data.domain.Pageable , ..))")
private void isMethodPageable () {
    log.info("in a Aspect point cut isPageableParameterAvailable()");
}