2017-06-14 1 views
1

J'ai le comportement étrange suivant.@AfterThrowing au printemps comportement différent

Lorsque j'utilise une méthode nommé pointcut le conseillé court avant que le corps de la méthode @AfterThrowing annoté. Mais si j'utilise un point-en-ligne, le @AfterThrowing annoté est exécuté en premier.

Pourquoi donc?

Voici le code:

@Component 
@Aspect 
public class CustomAspect { 

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

} 

résultats dans:

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ème résultat:

@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() + " ######"); 
    } 

} 

Et nous obtenons:

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 ###### 

Répondre

1

Votre code fonctionne comme prévu. Le conseil @AfterThrown a été exécuté après le lancement de l'exception.

La chose la plus délicate est avec System.out.println. Il appelle le PrintStream sous le capot. C'est un flux tamponné. Un flux Buffered est écrit dans la sortie (console) après qu'il se soit rempli, ou lorsque vous appelez explicitement Flush.

Donc, dans votre cas, cela dépend de la dynamique interne de la quantité de la pile est remplie et combien de déclarations d'impression ont pu s'exécuter avant autre thread stacktrace d'exception imprimée.

P.S. Essayez d'exécuter chacun de votre couple de solution de fois, et vous verrez que ###### Some message from the exception ###### est en cours d'impression avant et après la principale stacktrace dans un ordre aléatoire.