2017-06-14 5 views
1

Ich habe das folgende seltsame Verhalten.@AfterThrowing im Frühjahr unterschiedliches Verhalten

Wenn ich einen benannten Pointcut verwende, wird die empfohlene Methode vor dem Rumpf der @AfterThrowing annotierten Methode ausgeführt. Aber wenn ich einen Inline-Pointcut verwende, wird zuerst die @AfterThrowing-Annotation ausgeführt.

Warum so? Hier

ist der Code:

@Component 
@Aspect 
public class CustomAspect { 

    @AfterThrowing(pointcut = "execution(* throwAnException(..))", throwing = "exception") 
    public void adviceForExceptionThrowing(Exception exception) { 
     System.out.println("###### " + exception.getMessage() + " ######"); 
    } 

} 

Ergebnisse in:

INFO: Refreshing org.spring[email protected]5a10411: startup date [Wed Jun 14 15:51:26 EEST 2017]; root of context hierarchy 
###### Some message from the exception ###### 
Exception in thread "main" java.lang.Exception: Some message from the exception 

2. Ergebnis:

@Component 
@Aspect 
public class CustomAspect { 

    @Pointcut("execution(* throwAnException(..))") 
    private void pointcutForException() { 
    } 

    @AfterThrowing(pointcut = "pointcutForException()", throwing = "exception") 
    public void adviceForExceptionThrowing(Exception exception) { 
     System.out.println("###### " + exception.getMessage() + " ######"); 
    } 

} 

Und wir bekommen:

INFO: Refreshing org.spring[email protected]5a10411: startup date [Wed Jun 14 15:54:38 EEST 2017]; root of context hierarchy 
Exception in thread "main" java.lang.Exception: Some message from the exception 
    at blog.codingideas.aspects.SomeBean.throwAnException(SomeBean.java:13) 
    at blog.codingideas.aspects.SomeBean$$FastClassBySpringCGLIB$$97c62a5f.invoke(<generated>) 
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) 
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 
    at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673) 
    at blog.codingideas.aspects.SomeBean$$EnhancerBySpringCGLIB$$985c5826.throwAnException(<generated>) 
    at blog.codingideas.ApplicationMain.main(ApplicationMain.java:13) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) 
###### Some message from the exception ###### 

Antwort

1

Ihr Code funktioniert wie erwartet. Der @AfterThrown-Hinweis wurde ausgeführt, nachdem die Ausnahme ausgelöst wurde.

Die heikle Sache ist mit System.out.println. Es ruft den PrintStream unter der Haube auf. Dies ist ein gepufferter Stream. Ein gepufferter Stream wird in die Ausgabe (Konsole) geschrieben, nachdem er voll ist oder wenn Sie ihn explizit aufrufen.

Also hängt es in Ihrem Fall von der internen Dynamik ab, wie viel der Stapel voll ist und wie viele Druckanweisungen ausgeführt werden konnten, bevor ein anderer Thread eine gedruckte Ausnahme-Stapelverfolgung ausgeführt wurde.

P.S. Versuchen Sie, jede Ihrer Lösung einige Male auszuführen, und Sie werden feststellen, dass ###### Some message from the exception ###### vor und nach dem Main Stacktrace in zufälliger Reihenfolge gedruckt wird.

Verwandte Themen