我可以使用Spring AOP拦截方法中的空指针异常吗?

时间:2012-02-09 12:58:24

标签: java spring spring-aop

我们有一堆pdf报告类,在大量导入存档数据之后,当数据位丢失时偶尔会抛出空指针异常。 thing.getOtherThing().getText();将不会有OtherThing,报告将会失效。

我认为我们有几个选择

  1. 修复数据 - 不清楚数据在每种情况下应该是什么,在某些情况下是人为判断的问题
  2. 在任何地方放置尝试/捕获并重新抛出一个有用的例外来冒泡到用户 - 许多工作和丑陋的代码但对用户有用
  3. 无处不在地进行空检查 - 不,谢谢
  4. 处理DAO代码以在查询中执行coalesce / nvl并在缺少的字段(或库)中生成带有N / A的报告 - 确定但没有那么有用
  5. 或者......我们可以在这里用AOP做点什么吗?是否有可能拦截某些类/方法中抛出的nullpointers?拦截这些信息时可获得哪些级别的信息?请记住,方法中的多个位置可能会抛出空指针:(

    感谢。

2 个答案:

答案 0 :(得分:2)

Uff ..这可能会很痛苦,但我真诚地建议你通过你的代码并在任何合理的地方放置检查,为自己构建一个实用工具类,这样你就可以做类似的事情

MyUtilityHelper.checkNotNull (toCheck, elegantMessage)

然后让这个方法抛出一些你可以获得更多信息的东西。

AOP在这里真的不适用恕我直言,你不想做AOP的东西应该用顺序逻辑完成,只是因为代码更适合顺序处理...当你想要添加时AOP是合适的一个水平的功能层,如安全性,记录......

答案 1 :(得分:2)

AOP可能会帮助您找到解决方案,但是您需要在抛出异常之前采取措施,因为异常会导致您丢失太多的执行上下文。首先,当你写thing.getOtherThing.getText()getOtherThing一个奇怪名字或方法调用的字段时,你不小心忽略了括号?如果是后者,可以使用Spring AOP来拦截方法(提供的 thing实际上是一个bean)。如果没有,你将需要完整的AspectJ,因为Spring AOP不进行字段访问拦截(因为它是如何实现的)。

您的想法是使用@Around来定义切入点并获得如下建议:

static final OtherThing THE_DEFAULT_VALUE = ...;

@Around("execution(* getOtherThing())")
public Object supplyDefault(ProceedingJoinPoint pjp) throws Throwable {
    Object result = pjp.proceed();
    if (result == null)
        result = THE_DEFAULT_VALUE;
    return result;
}

或者,使用AspectJ(未经测试;我实际上没有使用AspectJ):

aspect ADefaultOtherThing {
    static final OtherThing THE_DEFAULT_VALUE = ...;

    OtherThing around(): get(OtherThing getOtherThing) {
        OtherThing result = proceed();
        if (result == null)
            result = THE_DEFAULT_VALUE;
        return result;
    }
}

不过,我还是怀疑这是否特别适合使用AOP。当然,将这样的业务逻辑直接放在代码中会更好吗?保证字段永远不会null看起来像是一个很好的不变量。