2

我正在使用 Spring 的 AOP 功能。我有课叫

class UserService {
    public User insertUserService(User user) throws PersistenceLayerException {
        System.out.println("UserServiceImpl_Two called: insertUserService method");

        if (user.id == 1) 
            throw new PersistenceLayerException();

        return null;
    }
}

现在,对该方法的调用insertUserService被一个拦截器拦截,该拦截器进行一些验证。这个验证拦截器抛出一个名为BusinessException. 现在,当抛出此异常时,Java 会抛出一个UndeclaredThrowableException因为BusinessExcepetion未在 throws of 中声明的原因insertUserService。有没有办法解决这个问题UndeclaredThrowableException而不必BusinessException在 throws 子句中声明。

原因insertUserService本身就没有抛出 a BusinessException,所以它看起来应该有办法解决。

4

3 回答 3

1

如果可行,一个想法是创建BusinessException一个 的子类RuntimeException,无论如何这更符合 Spring 哲学。

编辑:

您还询问是否有办法通过检查异常来执行此操作。您可能采取的一种方法是基于重新考虑您的UserService合同。“服务”(在服务 bean 的意义上)通常是更高级别的域概念,因此实际上可能更适合BusinessException从您的UserService合同中声明。然后,当存在较低级别的持久性问题时,您可以将其包装为BusinessException(如果BusinessException表示“对业务服务的调用失败”之类的通用内容),或者只声明两者BusinessException并且PersistenceLayerException如果您想要BusinessException具有狭义的含义(例如验证问题等)。

在这种情况下,您可能会使用UserServiceSpring Security UserDetailsService,它确实更面向持久性。如果是这样,那么上述想法可能不适用。但否则考虑这是一个选择。

说了这么多,制作BusinessExceptionaRuntimeException是最符合 Spring 实践的,并且可以说是最佳实践,原因我在这里描述。

于 2014-06-25T06:37:03.247 回答
1

我能想到的一种方法(因为您说 BusinessException 是已检查的异常),将您的异常与实际抛出的异常一起包装。如下所示,并在您的调用者中适当地处理它。无论如何,不​​建议在 PersistenceException 下包装业务异常(感谢 Wille 指出)

throw new PersistenceLayerException(new BusinessException(..));
于 2014-06-25T06:43:32.520 回答
0

我不熟悉Spring拦截器,但我相信它背后的逻辑将与标准 Java EE javax.interceptor.AroundInvoke完全相同:

定义一个插入业务方法的拦截器方法...方法可以抛出它们所插入的方法的 throws 子句允许的AroundInvoke任何异常。

所以它说你不应该抛出一个未由你用拦截器装饰的业务方法声明的检查异常。

实际上,不结合检查异常和 AOP 是很常见的做法。我认为使用 AOP 处理异常是使用检查异常的一种替代范例。

于 2015-10-22T09:37:47.710 回答