忽略bindInterceptor中一个类的调用

时间:2013-12-03 21:40:50

标签: java aop guice

我正在使用Guice为一个类中的所有方法创建一个拦截器,除了那些用我创建的特定类注释的方法:

这是AbstractModule:

public class MyModule extends AbstractModule {

    @Override
    protected void configure() {

        bindInterceptor(
                Matchers.subclassesOf(MyFacade.class),
                Matchers.not(Matchers.annotatedWith(DAO.class)),
                new MyInterceptor());
    }

}

现在,当同一个类(MethodInterceptor)中的另一个方法调用MyFacade MyFacade时,是否可以忽略public class MyFacade{ @DAO public void doSomething(){ ... } public void a(){ ... b(); } public void b(){ ... } } 中的所有方法?

例如:

{{1}}

我不希望拦截器拦截从方法a()到方法b()的调用。

谢谢!

1 个答案:

答案 0 :(得分:2)

被截获者没有简单的方法可以知道哪个班级正在调用它。此外,在大多数情况下,您可能希望调用b()来运行截获的方法 - 例如确保正确打开和关闭数据库事务。如果你需要确保只在外部呼叫上发生拦截,你必须要有点聪明。

选项1:重写拦截器以保持状态

考虑重写你的MethodInterceptor,让一个警卫检查它是否在截获的方法中间。请记住,bindInterceptor accepts instances,所以如果涉及到它,你可以在那里保持调用堆栈状态。这是不寻常的 - 拦截器通常被假定为无状态 - 所以记录得很好。

/**
 * Prevents internal interceptor calls from within intercepted methods.
 * Not thread safe.
 */
public abstract class GuardedInteceptor implements MethodInterceptor {
  private boolean executionInProgress = false;

  /** No-op if in the middle of an intercepted method. */
  public Object invoke(MethodInvocation invocation) throws Throwable {
    if (executionInProgress) {
      return invocation.proceed();
    }
    executionInProgress = true;
    Object returnValue = null;
    try {
      runBefore();
      returnValue = invocation.proceed();
      runAfter();
    } finally {
      executionInProgress = false;
    }
    return returnValue;
  }

  protected abstract void runBefore();
  protected abstract void runAfter();
}

选项2:重写截取的类以委托私有方法

在您的情况下,我会b()委托私人方法bInternal(),并在MyFacade中调用b()而不是{{1}}。 Guice AOP无法拦截私有方法,因此您无需担心注释或配置其他任何内容。这也允许各个系统选择是否调用可能被覆盖或截获的公共方法或有效最终的,可预测的私有方法。 AOP拦截是通过继承实现的,因此关于designing and documenting for inheritance的标准规则适用于此。