ШВ: Компонент слишком рано вводится в перехватчик?

Допустим, у меня есть следующий перехватчик в приложении 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() работает (поэтому монитор вводится правильно), myMonitor.b() не работает, потому что монитор уже равен нулю. документ Seam говорит: «Введенные значения удаляются (т. е. устанавливаются равными нулю) сразу после завершения и вывода метода».

Это то, что происходит? Могу ли я сделать что-то, чтобы сказать SEAM «еще не» «отключить» компонент? Я, конечно, также могу сделать что-то вроде XContext.get(..), но мне интересно, является ли это ошибкой или ошибкой с моей стороны. Спасибо!


person wilth    schedule 12.12.2009    source источник


Ответы (3)


Вместо этого попробуйте этот

Object response = null;

try {
    myMonitor.a();

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

return response;

с уважением,

person Arthur Ronald    schedule 12.12.2009

Избегайте использования инъекций.

Попробуйте обойти эту проблему. Я вижу, у вас есть какой-то мониторинг происходит. Посмотрите на этот перехватчик, который фиксирует количество времени, в течение которого метод выполняется в компонентах Seam. Попробуйте изменить свой код, чтобы он соответствовал этому.

Это прекрасно работает! Вот ссылка

person Shervin Asgari    schedule 12.02.2010
comment
@Shervin Приятно знать (+1), Шервин. В Seam Framework: Experience the Evolution of Java EE говорится, что вы можете избежать @In-jection, используя один метод установки без аннотации @In. - person Arthur Ronald; 14.03.2010

Шов работает как заявлено.

Вы можете просто игнорировать деинъекцию:

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(), оставив вам ссылку на сломанный прокси. Лучший совет — знать объем и жизненный цикл того, что вы сохраняете, поскольку вы «живете на грани».

person recampbell    schedule 19.02.2010
comment
Хм, извините, но я действительно не понимаю, как ваш код может мне помочь. Моя проблема в том, что в строке myMonitor.b() myMonitor имеет значение null. (то, что вы описываете во втором абзаце, - это то, что происходит). Я не понимаю, как это работает, как рекламируется, поскольку я предполагаю, что завершение метода включает в себя выполнение всех блоков finally {} - или я ошибаюсь? - person wilth; 19.04.2010