2

我真的开始关注 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
  • 事务处理
  • 消息传递

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

4

2 回答 2

3

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

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

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

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

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

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

使用 AOP,方法的主体变为:

executeSomeBusinessCode();
于 2012-06-08T12:10:37.103 回答
1

不确定“消息传递”和“持久性”是什么意思——你想发送什么消息?你想坚持什么?

如果你想保持方法调用的结果非常简单,请实现一个 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());

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

这有什么帮助。

于 2012-06-12T14:42:55.063 回答