2014-10-03 70 views
1

我有一個截取我的代碼中的很多方法的方面。我想知道如果joinPoint的簽名和聲明類型可以爲null。如果不是,那麼我的try ... catch就不是必需的了。是我的try catch塊嗎?

換句話說,是否需要在以下代碼中嘗試... catch塊?

private Object logPerfomanceInfo(ProceedingJoinPoint joinPoint) { 
     StringBuilder tag = new StringBuilder(); 
     try { 
      tag.append(joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); 
     } catch (Exception e) { 
      // Do not do anything, let the execution continue 
     } 
     StopWatch stopWatch = new StopWatch(tag.toString()); 
     Object result = joinPoint.proceed(); // continue on the intercepted method 
     stopWatch.stop(); 
     PerformanceUtils.logInPerf4jFormat(stopWatch.getStartTime(), stopWatch.getElapsedTime(), stopWatch.getTag(), stopWatch.getMessage(), getRemoteAddress()); 
     return result; 
    } 
+2

我不知道它是否可以是null,但我認爲如果你關心它是否爲null,而不是捕獲每個Exception,你應該檢查if(signature!= null) {...}。你當前的代碼將吞噬任何世界末日的錯誤報告,假裝它只是拋出了'NullPointerException'因爲沒有簽名。 – 5gon12eder 2014-10-03 01:15:05

+0

有些情況下,我已經看到這是必要的,但它們很少見。至少,如果你要吃掉整個異常,尤其是像Spring這樣的東西,*記錄警告。* – Compass 2014-10-03 03:34:00

回答

2

我在想,如果joinPoint的簽名和聲明類型都不能爲空。

不,他們不能。

驗證的一種方法是讀取the source code Spring的實現。

或者,我們可以轉向非常好的AspectJ文檔。 javadoc for JoinPoint#getSignature()狀態

返回連接點處的簽名。

而且Signature#getDeclaringTypeName()

返回聲明類型的完全限定名稱。

這兩個javadoc條目都非常具體關於它們返回的內容。他們中的任何一個返回null都沒有意義。

0

不,您的代碼不需要Try/Catch或任何throws子句。

1

由於Sotirios Delimanolis已經說過,每個連接點都有一個(非空)簽名。但我有一個關於你的代碼的其他部分爲你幾個提示:

  • 如果logPerfomanceInfo(..)是一個建議,那一定是public,不private。否則它不會編譯。
  • 您爲每個日誌記錄語句創建一個StringBuilder,但僅調用append(..)一次,使用+進行字符串連接。這使得字符串構建器毫無意義。
  • 替代手動連接聲明類和方法名稱,您可以使用Signature方法toString(),toShortString()toLongString()之一。這樣你得到一個類似的輸出,不需要連接任何東西。
  • 如果您使用多種方法,則爲每個呼叫創建一個StopWatch實例可能會很昂貴。無論如何,除了開始和消逝的時間,你不需要任何東西。您放入秒錶的標籤需要稍後提取,這也是開銷。爲什麼不直接調用日誌記錄方法?你不希望方面的建議比定時方法更昂貴,是嗎? ;-)
  • message從哪裏來的StopWatch?它以某種方式自動合成?它應該在使用之前設置,否則它是空的?

只是爲了說明,我的意思是這樣的:

@Around("execution(* *(..)) && !within(MyAspect) && !within(de.scrum_master.app.PerformanceUtils)") 
public Object logPerfomanceInfo(ProceedingJoinPoint joinPoint) { 
    long startTime = System.nanoTime(); 
    Object result = joinPoint.proceed(); 
    PerformanceUtils.logInPerf4jFormat(
     startTime, 
     System.nanoTime() - startTime, 
     joinPoint.getSignature().toShortString(), 
     "My log message", 
     getRemoteAddress() 
    ); 
    return result; 
} 

更新:另外,如果你想用你的想象StopWatch類,你可以添加另一個PerformanceUtils.logInPerf4jFormat(..)方法直接消耗而不是通過一個接一個地調用四個方法來促使呼叫者提取秒錶內部消息。這可能也可能應該隱藏在日誌記錄方法中以使調用代碼更清晰。

+0

感謝您的反饋意見。說得通。我會相應地做出改變。 – riship89 2014-10-03 18:14:52