是我的try catch块需要吗?

时间:2014-10-03 01:00:45

标签: java spring aop aspectj

我有一个方面在我的代码中拦截了很多方法。我想知道joinPoint的签名和声明类型是否可以为空。如果不是,那么我的尝试......捕获不是必需的。

换句话说,是否需要以下代码中的try ... 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;
    }

3 个答案:

答案 0 :(得分:2)

  

我想知道joinPoint的签名和声明类型是否可以为空。

不,他们不能。

要验证的一种方法(很长的路要走)是阅读Spring的实现the source code

或者,我们可以转向非常好的AspectJ文档。 javadoc for JoinPoint#getSignature()

  

返回连接点处的签名。

Signature#getDeclaringTypeName()

  

返回声明类型的完全限定名称。

两个javadoc条目都非常具体地说明了它们返回的内容。他们中的任何一个都返回null毫无意义。

答案 1 :(得分: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(..)方法直接使用StopWatch代替通过一个接一个地调用四个方法来促使调用者提取秒表内部。这可能并且可能应该隐藏在日志记录方法中,以使调用代码更清晰。

答案 2 :(得分:0)

没有你的代码不需要Try / Catch或任何throws子句。