2011-08-27 10 views
6

Soy bastante nuevo en AspectJ y tengo un problema que a pesar de algunas investigaciones que no puedo solucionar. Tengo el siguiente aspecto con respecto a un banco, el aspecto verifica si el saldo del Banco se mantiene después de cada invocación de método público.Recursion usando AspectJ

pointcut BankCheck(Bank bank): call(public * Bank.*(..)) && target(bank); 

Object around(Bank bank): BankCheck(bank) { 
    int balance = bank.getTotalBalance(); 
    Object result = proceed(bank); 
    if (balance != bank.getTotalBalance()) { 
     LOGGER.warn("The total balance of the bank is not equal."); 
    } else { 
     LOGGER.info("Ok"); 
    } 
    return result; 
} 

El problema es que en el aspecto utilizo el método bank.getTotalBalance(), que es en sí mismo un método banco público. Por lo tanto, el aspecto se recomienda siempre y este problema de recursión continúa hasta que se produce una excepción. ¿Hay alguna manera de solucionar esto, por ejemplo, desactivando el mecanismo de asesoramiento dentro del aspecto?

Respuesta

4

Prueba esto:

public aspect BankTotalBalanceAspect { 
    pointcut BankCheck(Bank bank): call(public * Bank.*(..)) && target(bank); 

    Object around(Bank bank): BankCheck(bank) && !within(BankTotalBalanceAspect) { 
     int balance = bank.getTotalBalance(); 
     Object result = proceed(bank); 
     if (balance != bank.getTotalBalance()) { 
      LOGGER.warn("The total balance of the bank is not equal."); 
     } else { 
      LOGGER.info("Ok"); 
     } 
     return result; 
    }  
} 
+2

Gracias, esto es exactamente lo que estaba buscando. –

0

No estoy muy familiarizado con la sintaxis de corte puntual de AspectJ, pero ¿tiene alguna forma de excluir la llamada getTotalBalance de su definición de corte puntual? Esto evitaría que ocurriera la recursión.

Además, su definición de punto de corte parece coincidir de manera muy amplia de todos modos: supongo que la comprobación de saldo que implemente en su aspecto debe ejecutarse para escribiendo métodos solamente. Por lo tanto, una llamada de solo lectura como getTotalBalance no debe coincidir de todos modos. ¿Tiene alguna forma de distinguir entre los métodos de solo lectura y escritura en la clase meta, e. gramo. por anotaciones de transacciones existentes o algo así?

De lo contrario, es posible que desee introducir dichas anotaciones (personalizadas) y ajustar su punto de corte para que coincida con todas las llamadas a métodos públicos que no están marcadas como de solo lectura. Pero esto significaría modificar el código en la clase objetivo, que no siempre es una opción. Pero YMMV.

+0

De hecho, sería posible hacer algunas anotaciones personalizadas y solucionar el problema de esa manera. La solución Inspite @Constantiner es mucho más fácil. Gracias de todos modos –