SEAM:在拦截器中“组件”“过早地”“撤消”?

时间:2009-12-12 08:50:30

标签: seam code-injection interceptor

假设我在SEAM应用程序中有以下拦截器:

public class MyInterceptor {
  @In
  private Monitor myMonitor;

  @AroundInvoke
  public Object aroundInvoke(InvocationContext ctx) throws Exception {
    try {
      myMonitor.a();
      return ctx.proceed();
    }
    finally {
      myMonitor.b();
    }
  }
}

myMonitor.a()有效(因此Monitor正确注入),myMonitor.b()失败,因为Monitor已经为null。 Seam Doc说:“在方法完成和退出后,注入的值立即被撤销(即设置为空)。”

那是怎么回事?我可以做些什么来告诉SEAM“尚未”“禁用”该组件吗?我当然也可以做一些像XContext.get(..)的事情,但我想知道这是一个错误还是我身边的错误。谢谢!

3 个答案:

答案 0 :(得分:1)

试试这个

Object response = null;

try {
    myMonitor.a();

    response = ctx.proceed();
} finally {
    myMonitor.b();
}

return response;

的问候,

答案 1 :(得分:1)

避免使用注射。

尝试解决此问题。我看到你正在进行某种监控。查看此拦截器,捕获在Seam组件中执行方法的时间。尝试修改代码以匹配该代码。

效果很好! 这是link

答案 2 :(得分:0)

Seam正如宣传的那样工作。

你可以忽略这种不当行为:

public class MyInterceptor {

  private Monitor myMonitor;

  @In
  private void setMonitor(Monitor aMonitor) {
     if (aMonitor != null) {
       myMonitor = aMonitor;
     }
  }


  @AroundInvoke
  public Object aroundInvoke(InvocationContext ctx) throws Exception {
    try {
      myMonitor.a();
      return ctx.proceed();
     }
     finally {
       myMonitor.b();
       myMonitor = null; //perform disinjection yourself
     }
  }
}

这里需要注意的是Seam正在为了某个原因而对该引用进行反对。 Seam希望控制“myMonitor”的生命周期和身份,并通过保留对它的引用,你不会遵守与Seam的合同。这可能会导致意外行为。

例如,如果myMonitor出于某种原因在无状态范围内,Seam可能会在ctx.proceed()返回之前销毁它,留下您对破坏的代理的引用。最好的建议是了解你所保留的范围和生命周期,因为你“生活在边缘。”