2012-06-08 13 views
16

Ich sehe, dass Guice und Spring AOP Alliance unter der Haube für Methodenabfangen verwenden, und ich habe versucht herauszufinden, wie man AOP Alliance abfangen und mit bestimmten Ausnahmen umgehen kann, so dass ich sie nicht behalten muss in jedem catch Block den gleichen Code immer und immer wieder schreiben.AOP Exception Behandlung

Aber nach dem Spiel bewerten, es sieht nicht wie AOP Allianz bietet jede mögliche Weise geworfen abzufangen Throwable s derart, dass der Handler/Interceptor einige Dinge tun können (log die Ausnahme, etc.) und dann bestimmen, ob die Ausnahme weiter zu verbreiten oder nur zu erholen nach der Zeile in der nächsten Zeile zurück, die die Ausnahme ausgelöst hat:

HerpDerp hd = null; 

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

Manny.pacquiao(); 

ich bin für eine AOP-Ausnahmebehandlung suchen, die RuntimeException abfangen würde und verwenden Sie Geschäftslogik, um zu entscheiden, ob Sie es weiter verbreiten oder bei dem Aufruf Manny.pacquioa() wiederherstellen möchten .

  • Wenn es einfach nicht möglich, ist dies in Java zu tun, bitte mich
  • Unabhängig davon wissen lassen, ob sie möglich, dies in Java zu tun, gibt es einen Weg geworfen Exception mit AOP Allianz abzufangen oder Muss ich woanders hingehen? Und wenn ich irgendwo anders hingehen muss, wo? AspectJ?

Vielen Dank!

Antwort

30

Sie können Ausnahmen mit Spring AOP abfangen, aber ich weiß nicht, ob das Ihrer Anforderung für ein reines Java-Framework entspricht.

Mit Spring, können Sie einen einfachen AOP Abfangjäger als so etwas wie schreiben:

@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."); 
    } 
} 
} 

aber es gibt keinen Weg zum Rufmethode zurückzukehren oder Verarbeitung auf der nachfolgenden Zeile fortgesetzt werden. Wenn Sie jedoch die Ausnahme hier behandeln, wird die Kette nicht aufgebläht, wenn Sie sie nicht selbst erneut auslösen.

1

zu „fangen“ abgefangene Ausnahmen mit AspectJ, können Sie den folgenden Aspekt verwenden:

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 
} 

Ich glaube nicht, ist es möglich, „zurückgehen“, um die Ausführungspunkt.

+0

Dank @Wim fangen - ist AOP-basierte Ausnahmebehandlung ist mit AOP Alliance nicht möglich? – IAmYourFaja

+0

Ich glaube nicht. Wenn Sie die [spring docs] (http://static.springsource.org/spring/docs/3.1.1.RELEASE/spring-framework-reference/html/aop.html) überprüfen, wird folgendes angezeigt: 'Join point : ein Punkt während der Ausführung eines Programms, z. B. die Ausführung einer Methode oder die Behandlung einer Ausnahme. In Spring AOP stellt ein Join-Punkt immer eine Methodenausführung dar. –

+0

Konnte [ConstructorInterceptor] (http://aopalliance.sourceforge.net/doc/org/aopalliance/intercept/ConstructorInterceptor.html) irgendwie gehackt werden, um Ausnahmen abzufangen (wie sie gebaut sind)? – IAmYourFaja

3

Es gibt einen Grund, dass dies nicht existiert. Sie müssten die Blockstruktur Ihres Codes so umschreiben, als hätten Sie den try/catch-Block an erster Stelle geschrieben. Dies scheint mir potentiell mit variablem Umfang und anderen Dingen zu tun zu haben. Sie bitten AOP, den Byte-Code so umzuschreiben, dass er dem folgenden Code entspricht, und das ist ziemlich neu geschrieben.

HerpDerp hd = null; 

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

Manny.pacquiao(); 
1

@ 4herpsand7derpsago Wenn das, was Sie versuchen, die geworfene Ausnahme mit AOP zu fangen zu tun ist, verschiedene Aufgaben auszuführen, es zu verarbeiten und dann an den Code kommt zurück, wo die Ausnahme ursprünglich geworfen, ich glaube, Sie vermissen verstehen das Konzept von AOP.

Wie Sie in Ihrem Code hinweisen

HerpDerp hd = null; 

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

Manny.pacquiao(); 

Wenn Sie möchten, dass Ihre AOP RuntimeException zu fangen, führen einige Dinge, die es zu handhaben und kommt zurück zu Manny.pacquiao();, ist die Antwort kann man nicht. Der Grund ist, weil wenn der RuntimeException von AOP geworfen und gefangen wird, der Stapel bereits bei Ihrem AOP-Code ist. Sie können nicht zurückkehren, um auszuführen. Der einzige Weg, wenn Sie Many.pacquiao(); fortsetzen wollen Ausführung ist durch try-finally Block unter Verwendung als

HerpDerp hd = null; 

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

folgen Nur dann wird Ihr Many.pacquiao() ausgeführt werden sollen, aber bevor Ihr AOP die RuntimeException