2

我的想法是使用AspectJ来捕获注释方法中的异常,并且如果引发任何异常,注释的方法应该尝试再次运行。我主要是按照这个教程(http://zoftware.blogspot.cz/2008/02/using-aspectj-and-java-annotations-to_23.html),但我无法让它工作。一切都应该没问题,但事实并非如此。终于捕获异常,并且抛出了许多异常,而不仅仅是一个异常。抓住我的方面似乎根本不工作。我使用AspectJ 1.7.3。 该代码是...@Around(AspectJ)中没有捕获的异常

译注:

@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface RetryIfFailed { 

    int maxRetries() default 5; 
} 

注解的方法:

@RetryIfFailed(maxRetries = 3) 
private User showUser(String userName) { 
    try { 
     return twitter.showUser(userName); 
    } catch (TwitterException e) { 
     System.out.println("I am catch inside showUser"); 
    } 
    return null; 
} 

看点:

@Around("call(@RetryIfFailed * *..*(..))") 
    public Object retryMaxRetriesTimes(ProceedingJoinPoint thisJoinPoint) throws Throwable { 
     System.out.println("Entering retryMax..."); 
     Method method = ((MethodSignature) thisJoinPoint.getSignature()).getMethod(); 
     RetryIfFailed annotation = method.getAnnotation(RetryIfFailed.class); 
     int retries = annotation.maxRetries(); 

     Object ret = null; 
     while (retries > 0) { 
      try { 
       System.out.println("Before proceeding... Retries=" + retries); 
       ret = thisJoinPoint.proceed(); 
      } catch (Throwable e) { 
       System.out.println("I am catched in RetryMax "); 
       retries--; 
       if (retries == 0) { 
        System.out.println("Exception caught. Rethrowing..." + e); 
        throw new ConnectionErrorException("Twitter service failed to establish connection", e); 
       } 
      } finally { 
       System.out.println("Finally block..." + retries); 
       if (ret != null) { 
        System.out.println("Object returned: " + ret); 
        return ret; 
       } 

       System.out.println("Decresing retries to" + retries); 
       retries--; 
       if (retries == 0) { 
        throw new ConnectionErrorException("It should not get here."); 
       } 
      } 
     } 

     //should never be reached 
     return null; 
    } 
} 

Maven配置:

<!-- Build with AspectJ--> 
    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.codehaus.mojo</groupId> 
       <artifactId>aspectj-maven-plugin</artifactId> 
       <version>1.5</version> 
       <configuration> 
        <source>1.7</source> 
        <target>1.7</target> 
        <complianceLevel>1.7</complianceLevel> 
        <verbose>true</verbose> 
       </configuration> 
       <executions> 
        <execution> 
         <goals> 
          <goal>compile</goal> 
         </goals> 
        </execution> 
       </executions> 
       <dependencies> 
       </dependencies> 
      </plugin> 
     </plugins> 
    </build> 

输出:

Entering retryMax... 
Before proceeding... Retries=3 
I am catch inside showUser 
Finally block...3 
Decresing retries to3 
Before proceeding... Retries=2 
I am catch inside showUser 
Finally block...2 
Decresing retries to2 
Before proceeding... Retries=1 
I am catch inside showUser 
Finally block...1 
Decresing retries to1 
Exception in thread "main" ...<path>....ConnectionErrorException: It should not get here. 
     at ...<stackTrace follows>... 

感谢您的任何意见:)。

编辑

由于mvieghofer建议,我从来没有重新抛出异常。我期待@Around在里面捕获异常twitter.showUser(),那是错误的。如果有人对解决方案感兴趣,可以在这里:

@RetryIfFailed 
    public static User showUser(String userName) throws ConnectionErrorException { 
     try { 
      return twitter.showUser(userName); 
     } catch (TwitterException e) { 
      throw new ConnectionErrorException(exceptionMessage, e); 
     } 
    } 
+1

代码看起来像它的运行,因为它应该是。你永远不会抛出一个twitter异常。你应该使用afterthrowing,并在重试次数为0时重新抛出。 – aepurniet

回答

2

AspectJ有一个抛出异常的建议。

你可能有这样的事情:

aspect A { 
    pointcut publicCall(): call(@RetryIfFailed * *..*(..)); 
    after() throwing (TwitterExepction e): publicCall() { 
    System.out.println("Threw an exception: " + e); 
    } 

}

你也应该重新抛出里面你showUser法TwitterException。有关after()投掷建议的更多信息,请参阅this link

+0

是的,但这不是问题。我抛出ConnectionErrorException,但在我注释的方法抛出了异常。它被抛出3次 - 基本上意味着“ret = thisJoinPoint.proceed();”确实执行了3次,但异常没有被抓到方面(“catch(Throwable e)”) – Samuel

+0

好吧,我会更新答案 – mvieghofer

+0

我希望这可以帮助你:) – mvieghofer