【问题标题】:AOP-Based Persistence, Transactions & Messaging by Example基于 AOP 的持久性、事务和消息传递示例
【发布时间】:2012-06-12 22:42:55
【问题描述】:

我真的开始关注 AOP,并且非常喜欢抽象出横切关注点并将其从我的核心业务代码中删除的想法。到目前为止,我一直在阅读 AOP Alliance(我认为这是 Guice 和 Spring AOP 的主力)和 AspectJ。

不幸的是,当我们谈论比简单的方法拦截更高级的东西时,很难找到好的、有效的 Java AOP 代码示例。我一遍又一遍地阅读如何使用 AOP 实现主要的 Java EE 概念,例如持久性、事务处理和消息传递,但在我的一生中,我找不到任何这样的例子!

归根结底,AOP 归根结底就是方法拦截(除非我在这里遗漏了主要的东西)。所以如果是这样的话,并且给定方法拦截器的一般形式:

// Using AOP Alliance for this example
public class MyInterceptor implements MethodInterceptor {
    public Object invoke(MethodInvocation inv) {
        // Run this code before executing inv.
        preInvocation();

        Object result = inv.proceed();

        // Run this code after executing inv.
        postInvocation();
    }

    // ...
}

鉴于此,有人可以提供具体代码示例,说明如何通过方法拦截将这些 Java EE 概念中的每一个委托给 AOP:

  • 持久性/ORM
  • 事务处理
  • 消息传递

我想我只是很难连接所有的点并通过“树木”看到“森林”。提前致谢!

【问题讨论】:

  • 虽然 AOP 一开始可能令人兴奋,但请注意代码中“自动”的后果...没有那么坚固的把手。像所有事物一样,适度是很棒的。
  • 我真的建议为此使用注释,而不是纯粹的代码外 AOP 编织,它更容易遵循。对此有任何兴趣,或者您是否真的在寻找具有事务信息的线程局部变量存在的示例?我不确定 AOP 会在消息传递中添加什么,您在寻找什么?
  • 我是brand AOP 新手,我正在尝试查看我在reading about 中工作的代码示例。是的,出于几个原因,我绝对希望最终使用注释(方法拦截)而不是字节码编织。我正在寻找的是一个可用于持久性或消息传递的 AOP 方法拦截器的示例(这意味着,当一个方法执行时,它被拦截并且某种持久性或面向消息传递的代码作为它的建议执行)。

标签: java transactions persistence aop message


【解决方案1】:

不知道持久性和消息传递,但对于事务,我可以解释。我以 Spring 为例。

您可以配置 Spring bean(通常是服务层 bean),以便在这些 bean 上调用的每个方法都将被事务拦截器拦截。这个拦截器通常会做以下事情:

  • 查看事务是否已经绑定到当前线程
  • 如果没有,则启动事务并将其绑定到当前线程
  • 调用方法
  • 如果事务是通过该方法拦截启动的,并且该方法没有抛出运行时异常,则提交该事务
  • 如果事务是通过该方法拦截启动的,并且该方法抛出了运行时异常,则回滚该事务
  • 将事务与当前线程解除绑定

没有事务方面的事务方法将不得不做这样的事情:

try {
    userTransaction.begin();
    executeSomeBusinessCode();
    userTransaction.commit();
}
catch (RuntimeException e) {
    userTransaction.rollback();
}

它很麻烦,容易出错,甚至不处理事务传播、新事务等。

使用AOP,方法体变成:

executeSomeBusinessCode();

【讨论】:

  • 谢谢@JB。 +1 优秀的交易示例,但我正在寻找持久性和消息传递示例,到目前为止还没有提供。
【解决方案2】:

不确定您所说的“消息传递”和“持久性”是什么意思 - 您要发送什么消息?你想坚持什么?

如果你想保持方法调用的结果非常简单,请实现 MethodInterceptor:

public Object invoke(MethodInvocation invocation) throws Throwable {
    Object result = invocation.proceed();
    myPersistenceMethod(invocation, result);
    return result;
}

然后你可以定义一个注解并为注解的方法保留方法结果。例如。在 Guice 模块中:

 bindInterceptor(Matchers.any(), Matchers.annotatedWith(MyPersistenceAnnotation.class),
            new MyPersistenceInterceptor());

主要问题是如何构建持久性“键” - 最明显的事情是调用方法和参数,但由于这都是基于反射的,因此如果您开始假设某些方法,则无需编译时检查有一定的论据。

这有什么帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 2016-01-07
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    • 1970-01-01
    • 2014-02-05
    相关资源
    最近更新 更多