2012-06-08 11 views
16

Vedo che Guice e Spring usano AOP Alliance per intercettazioni di metodo, e ho cercato di capire come ottenere AOP Alliance per intercettare e gestire alcune eccezioni, quindi non devo tenere scrivere lo stesso codice più e più volte all'interno di ogni blocco catch.Gestione eccezioni AOP

Ma dopo aver esaminato il gioco, non sembra AOP Alliance fornisce un modo per intercettare gettati Throwable s in modo tale che il gestore/intercettore può fare alcune cose (log eccezione, ecc) e poi determinare o meno di propagare l'eccezione ogni ulteriore o per recuperare appena tornato alla riga successiva seguendo la linea che ha generato l'eccezione:

HerpDerp hd = null; 

if(hd == null) 
    throw new RuntimeException("Herpyl derp!"); 

Manny.pacquiao(); 

sto cercando un meccanismo di gestione delle eccezioni AOP che intercettare il RuntimeException e utilizzare la logica aziendale per decidere se continuare a diffonderlo o ripristinarlo alla chiamata Manny.pacquioa() .

  • Se è solo non è possibile fare questo in Java, per favore fatemelo sapere
  • Indipendentemente dal fatto che o non la sua possibile fare questo in Java, c'è un modo per intercettare Eccezione generata con AOP Alliance o devo andare da qualche altra parte. E se devo andare da qualche altra parte, dove? AspectJ?

Grazie!

risposta

30

È possibile rilevare eccezioni con Spring AOP, ma non so se questo corrisponde ai requisiti per un framework Java puro.

Con molla, è possibile scrivere un semplice intercettore AOP come qualcosa di simile:

@Aspect 
public class ErrorInterceptor{ 
@AfterThrowing(pointcut = "execution(* com.mycompany.package..* (..))", throwing = "ex") 
public void errorInterceptor(WidgetException ex) { 
    if (logger.isDebugEnabled()) { 
     logger.debug("Error Message Interceptor started"); 
    } 

    // DO SOMETHING HERE WITH EX 
    logger.debug(ex.getCause().getMessage()); 


    if (logger.isDebugEnabled()) { 
     logger.debug("Error Message Interceptor finished."); 
    } 
} 
} 

ma non c'è modo di tornare al metodo chiamante o continuare l'elaborazione sulla linea successiva. Tuttavia, se gestisci l'eccezione qui, non farà esplodere la catena a meno che non la riposi da solo.

1

Per "catturare" le eccezioni non gestite fanno con AspectJ, è possibile utilizzare il seguente aspetto:

pointcut uncaughtExceptionScope() : 
    (execution(* com.mycompany.myrootpackage..Main.main(..)) 
    || execution(* java.util.concurrent.Callable+.call()) 
    || execution(* java.lang.Runnable+.run()) 
    )); 

after() throwing(Throwable t) : uncaughtExceptionScope() && !cflow(adviceexecution()) { 
    handleException(thisJoinPoint, t); 
} 

protected void handleException(JoinPoint jp, Throwable t) 
{ 
    // handle exception here 
} 

non credo che sia possibile "tornare indietro" al punto di esecuzione.

+0

Grazie @Wim - è basato su AOP gestione delle eccezioni come questa non è possibile con AOP Alliance? – IAmYourFaja

+0

Io non la penso così. Se si seleziona [spring docs] (http://static.springsource.org/spring/docs/3.1.1.RELEASE/spring-framework-reference/html/aop.html), viene visualizzato questo: 'Punto di unione : un punto durante l'esecuzione di un programma, come l'esecuzione di un metodo o la gestione di un'eccezione. In Spring AOP, un join point rappresenta sempre un'esecuzione del metodo. –

+0

Potrebbe [ConstructorInterceptor] (http://aopalliance.sourceforge.net/doc/org/aopalliance/intercept/ConstructorInterceptor.html) essere in qualche modo violato per intercettare le eccezioni (come sono costruiti)? – IAmYourFaja

3

C'è un motivo per cui questo non esiste. Richiederebbe riscrivere la struttura a blocchi del codice come se avessi scritto il blocco try/catch in primo luogo. Questo, a mio parere, potenzialmente ha un effetto devastante con portata variabile e altre cose. Stai chiedendo ad AOP di riscrivere il codice byte in modo che assomigli al seguente codice, ed è piuttosto una riscrittura.

HerpDerp hd = null; 

try { 
    if(hd == null) 
     throw new RuntimeException("Herpyl derp!"); 
} catch(RuntimeException e) { 
    if (someConditionIsMet) { 
     throw e; 
    } 
} 

Manny.pacquiao(); 
1

@ 4herpsand7derpsago Se state cercando di fare è quello di catturare l'eccezione generata utilizzando AOP per eseguire vari compiti per gestire la cosa e poi torna al codice in cui l'eccezione originariamente lanciata, penso che ti manca capire il concetto di AOP.

Come fai notare nel codice

HerpDerp hd = null; 

if(hd == null) 
throw new RuntimeException("Herpyl derp!"); 

Manny.pacquiao(); 

Se si desidera AOP per catturare la vostra RuntimeException, eseguire alcune cose per gestire la cosa e torna al Manny.pacquiao();, la risposta è non si può. Il motivo è perché quando RuntimeException viene lanciato e catturato da AOP, lo stack è già al codice AOP. non puoi tornare ad eseguire Many.pacquiao();. L'unico modo se si desidera continuare l'esecuzione Many.pacquiao(); è quello di utilizzare try-finally blocco come seguire

HerpDerp hd = null; 

try { 
    if(hd == null) 
     throw new RuntimeException("Herpyl derp!"); 
} finally { 
    Manny.pacquiao(); 
} 

Solo allora la vostra otterrà eseguito Many.pacquiao(), ma prima AOP prendere il RuntimeException