【问题标题】:Grails: various problems around method proxyingGrails:围绕方法代理的各种问题
【发布时间】:2014-06-16 23:26:48
【问题描述】:

我的公司正在尝试实施一个审计服务,如果该方法使用特定注释进行注释,该服务将拦截对该服务的方法调用。例如:

class FooService {

  @Audit
  void pleaseAuditMe() {
    // some important code
  }
}

我们实现这一点的第一个尝试是使用 Spring AOP 将带注释的方法与 AOP 代理一起包装,该代理将记录我们在执行方法之前和之后需要的审计数据。虽然我们能够使审计工作,但解决方案并不好,因为如果检查了异常类型并且未在被代理的方法上声明,AOP 代理将包装任何抛出 UndeclaredThrowableException 的异常。鉴于 Groovy 和 Grails 的性质(即通常不声明已检查的异常),在我们所有的方法上遍历并声明确切的异常类型确实没有意义。

另外,我们尝试通过元类 mixins 来实现该功能。完成这项工作后,我们意识到 CompileStatic 上下文中的任何方法调用都不会通过元类,因此不会调用我们的代理逻辑。

这似乎是 Grails 世界中“已解决的问题”,但我们无法弄清楚。我们想要:

一种允许我们代理方法调用而不强制我们重写所有异常处理/声明的解决方案,并且无论我们是否处于编译静态上下文中,它都可以工作。

【问题讨论】:

    标签: spring grails groovy


    【解决方案1】:

    您可以使用由审核注释触发的 AST 转换来执行此操作。这就是最近版本的 Grails 对 Transactional 注解所做的事情。这避免了使用运行时代理的需要,并且如果操作正确,对 CompileStatic 完全友好。

    【讨论】:

    • 这是一个有趣的想法,看起来确实可行。这似乎也像是重新发明了一个肯定有人已经发明的轮子。是否没有在 Grails 中实际工作的方法代理方法?
    • 是的,有。然而,一般来说,我们尽可能远离运行时代理。事务性就是其中一个例子。如果这确实是你想做的,你可以做所有标准的 Spring 代理。如果我正在实现您所描述的内容,我会在 AST 转换中进行。这样做有很多好处,包括性能、从 Java 调用的能力、提高单元可测试性而无需创建代理(代码直接编译到类中)等。
    • 对于这里列出的所有缺点groovy.codehaus.org/Building+AST+Guide 我非常犹豫是否要在 AST 中实现它。我没有内部 AST 专业知识,而且从一个版本到另一个版本的 Groovy 似乎很脆弱。这段审计代码将被插入到我们所有最关键的业务代码中,因此动态学习一种新的、非常复杂的技术似乎风险太大。我真的很想在没有这些风险的工厂运行时代理的直接运行中实现这一点。对我来说,没有现成的解决方案似乎真的很奇怪。
    • 有一个开箱即用的解决方案。我觉得你会断言没有。
    • 如果您想使用运行时代理,请执行此操作。我提出了一个我认为是个好主意的替代方案。如果运行时代理让您开心,那么就这样做。你有很大的灵活性,因为 Spring 在这一切之下。 Spring 为这类事情提供了很多选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    • 2011-06-23
    • 2016-10-23
    相关资源
    最近更新 更多