有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java我可以在使用SpringAOP的方法中截获空指针异常吗?

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

在我看来,我们有几个选择

  1. 修复数据-不太清楚在每种情况下数据应该是什么,在某些情况下是人类判断的问题
  2. 将try/catch放在所有地方,并重新抛出一个有用的异常,以向用户显示-大量工作和难看的代码,但对用户有用
  3. 将空支票放在所有地方-不,谢谢
  4. 使用DAO代码在查询中执行coalesce/nvl,并在缺少的字段(或银行)中生成带有N/A的报告-可以,但没有那么有用

或者。。。我们能在这里用AOP做点什么吗?是否可以拦截某些类/方法中抛出的空指针?截获这些信息时,可用的信息级别是什么?请记住,方法中的多个位置可能会抛出空指针:(

谢谢


共 (2) 个答案

  1. # 1 楼答案

    不明飞行物。。这可能会很痛苦,但我真诚地建议您仔细检查代码,在任何合理的地方检查null,为自己构建一个实用程序类,这样您就可以执行以下操作

    MyUtilityHelper.checkNotNull (toCheck, elegantMessage)

    让这个方法抛出一些你能得到更多信息的东西

    AOP在这里真的不适用IMHO,你不想用AOP做那些应该用顺序逻辑来做的事情,只是因为代码更适合顺序处理。。。当您想要添加一个水平层的功能时,AOP是合适的,比如安全性、日志

  2. # 2 楼答案

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

    想法是使用@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似乎是一个精细的不变量