2014-10-03 65 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