Domanda
Sto usando AspectJ per consigliare tutti i metodi pubblici che hanno un argomento di una classe scelta. Ho provato quanto segue:
pointcut permissionCheckMethods(Session sess) :
(execution(public * *(.., Session)) && args(*, sess));
Funziona meravigliosamente con metodi con almeno 2 argomenti:
public void delete(Object item, Session currentSession);
ma non funziona con metodi come:
public List listAll(Session currentSession);
Come posso cambiare il mio pointcut per avvisare entrambe le esecuzioni dei metodi? In altre parole: mi aspettavo che " .. " carattere jolly per rappresentare "zero o più argomenti", ma sembra che significhi invece "uno o più" ...
Soluzione
Oh beh ... ci ho lavorato con questo brutto trucco. Aspetto ancora che qualcuno si presenti con un " ufficiale " definizione del punto.
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);
}
Altri suggerimenti
Che ne dici di:
pointcut permissionCheckMethods(Session sess) :
(execution(public * *(..)) && args(.., sess));
Immagino che questo corrisponderà se l'ultimo (o unico) argomento è di tipo Sessione. Scambiando le posizioni di args puoi anche abbinare il primo o il solo. Ma non so se è possibile abbinare qualsiasi posizione arbitraria.
Non posso estendere la sintassi di AspectJ per te, ma posso offrire una soluzione alternativa. Ma prima lasciami spiegare perché non è possibile fare ciò che vuoi con una definizione args
in un punto preciso: perché se corrispondessi al tuo parametro EhealthSession
ovunque nella firma del metodo , come dovrebbe AspectJ gestire il caso in cui la firma contenga più parametri di quella classe? Il significato di eheSess
sarebbe ambiguo.
Ora la soluzione alternativa: potrebbe essere più lenta - quanto dipende dal tuo ambiente, basta testarlo - ma potresti avere il punto di corrispondenza corrispondente a tutti i metodi potenziali indipendentemente dal loro elenco di parametri e quindi lasciare che il consiglio trovi il parametro di cui hai bisogno ispezionando l'elenco dei parametri:
pointcut permissionCheckMethods() : execution(public * *(..));
before() throws AuthorizationException : permissionCheckMethods() {
for (Object arg : thisJoinPoint.getArgs()) {
if (arg instanceof EhealthSession)
check(arg, thisJoinPointStaticPart.getSignature());
}
}
PS: forse puoi restringere lo stato attivo tramite all'interno di (SomeBaseClass +)
o all'interno di (* Postfix)
o all'interno di (com.company.package .. * )
per non applicare i consigli all'intero universo.
Devi usare .. (punti doppi) alla fine e all'inizio come segue:
pointcut permissionCheckMethods(Session sess) :
(execution(public * *(.., Session , ..)) );
Elimina anche & amp; & amp; args (*, sess)
perché ciò significa che ti aspetti di catturare solo quei metodi con qualunque tipo per il primo parametro ma sess
come secondo parametro e non più di 2 parametri anche ..