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

发布于 2025-01-03 19:26:31 字数 484 浏览 2 评论 0原文

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

正如我所见,我们有几个选项

  1. 修复数据 - 不太清楚每种情况下的数据应该是什么,在某些情况下是人为判断的问题
  2. 将 try/catch 到处放置并重新抛出一个有用的异常以向用户冒泡- 大量工作和丑陋的代码,但对用户有用
  3. 在各处放置空检查 - 不,谢谢
  4. 在 DAO 代码上工作,在查询中进行合并/nvl 并在缺失字段(或银行)中生成 N/A 的报告 - 好的但没有那么有用

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

谢谢。

We have a bunch of pdf report classes which after a mass import of archived data have started occaisonally throwing null pointer exceptions when bits of data are missing e.g. thing.getOtherThing().getText(); will not have an OtherThing and the report will fall over.

As I see it we have a few options

  1. Fix the data - not so clear what the data should be in every case and is a matter of human judgement in some cases
  2. Put try/catches everywhere and rethrow a useful exception to bubble up to the user - a lot of work and ugly code but usefull to the users
  3. Put null checks everywhere - no thanks
  4. Work on the DAO code to do coalesce/nvl in the queries and generate reports with N/A in the missing fields (or banks) - ok but no so usefull

Or ... can we do something with AOP here? Is it possible to intercept nullpointers thrown in certain classes/methods? What level of information is available when these are intercepted? Bear in mind that multiple places in a method could throw null pointers :(

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

探春 2025-01-10 19:26:31

呃..这可能很痛苦,但我真诚地建议您仔细检查您的代码,并在任何合理的地方检查 null ,为自己构建一个实用程序类,这样您就可以执行类似

MyUtilityHelper.checkNotNull (toCheck, beautifulMessage)

并让该方法抛出一些您可以获得更多信息的内容。

AOP在这里确实不适用恕我直言,你不想用AOP做应该用顺序逻辑完成的事情,只是因为代码更适合顺序处理......当你想添加水平层时AOP适合功能,例如安全性、日志记录......

Uff.. It might be painful, but I sincerely would recommend you to go tgrough your code and put the checks for null wherever is sensible, build for yourself a utility class so you can do something like

MyUtilityHelper.checkNotNull (toCheck, elegantMessage)

And make that method throw something which you can have more information about.

AOP is really not applicable here IMHO, you don't want to do with AOP stuff that is supposed to be done with sequential logic, just because code is better for sequential processing... AOP is suitable when you want to add a horizontal layer of functionality, like security, logging...

赢得她心 2025-01-10 19:26:31

AOP 可能会帮助您找到解决方案,但您需要在抛出异常之前采取行动,因为异常会导致您丢失太多执行上下文。首先,当您编写 thing.getOtherThing.getText() 时, getOtherThing 是一个具有奇怪名称的字段或您不小心省略了括号的方法调用?如果是后者,可以使用Spring AOP来拦截方法(provided 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 似乎是一个很好的不变量。

AOP could potentially help you reach a solution, but you need to take action before the exception is thrown because an exception will cause you to lose too much execution context. Firstly, when you write thing.getOtherThing.getText() is getOtherThing a field with an odd name or a method call that you accidentally omitted the parentheses from? If it is the latter, you can use Spring AOP to intercept the method (provided thing is actually a bean). If not, you'll need full AspectJ as Spring AOP doesn't do field access interception (because of how it is implemented).

The idea is that you use @Around to define the pointcut and have advice like this:

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;
}

Or, with AspectJ (untested; I've not actually used AspectJ for anything):

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;
    }
}

Still, I'd question whether this is a particularly good use of AOP. Surely it would be better to put such business logic directly in the code? Guaranteeing that a field is never null would seem like a fine invariant.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文