Pergunta

Eu estou usando AspectJ para aconselhamento todos os métodos públicos que têm um argumento de uma classe escolhida. Eu tentei o seguinte:

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

Isso está funcionando maravilhosamente para métodos com pelo menos 2 argumentos:

public void delete(Object item, Session currentSession);

mas não funciona com métodos como:

public List listAll(Session currentSession);

Como posso mudar o meu pointcut a conselhos ambas as execuções métodos? Em outras palavras: eu esperava que o ".." curinga para representar 'zero ou mais argumentos', mas parece que isso significa em vez 'um ou mais' ...

Foi útil?

Solução

Oh, bem ... eu trabalhei que por aí com esse truque sujo. Ainda à espera de alguém para mostrar-se com uma definição pointcut "oficial".

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);
}

Outras dicas

Como sobre: ??

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

Eu acho que isso irá corresponder se o argumento último (ou único) é do tipo de sessão. Trocando as posições dos argumentos que você também pode combinar primeiro-ou-somente. Mas eu não sei se encontrando qualquer posição arbitrária é possível.

Eu não posso estender sintaxe AspectJ para você, mas eu posso oferecer uma solução alternativa. Mas, primeiro, deixe-me explicar por que não é possível fazer o que quiser com uma definição args em um pointcut: porque se você iria coincidir com o seu parâmetro EhealthSession em qualquer lugar dentro da assinatura do método, como deve AspectJ lidar com o caso que a assinatura contém vários parâmetros de essa classe? O significado de eheSess seria ambíguo.

Agora, a solução alternativa: Pode ser mais lento - o quanto depende do seu ambiente, assim testá-lo - mas você poderia apenas ter o pointcut corresponder a todos os métodos potenciais, independentemente da sua lista de parâmetros e, em seguida, deixar o conselho encontrar o parâmetro que você precisa, inspecionando a lista de parâmetros:

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

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

P.S .: Talvez você possa estreitar o foco via within(SomeBaseClass+) ou within(*Postfix) ou within(com.company.package..*) de modo a não aplicar o conselho para todo o universo.

Você tem que usar .. (o dobro de pontos) no final e no início da seguinte forma:

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

Também se livrar off && args(*, sess) porque isso significa que você espera para pegar apenas os métodos com qualquer tipo para o primeiro param mas sess como segundo param e não mais de 2 params bem ..

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top