0

我有两个 ManagedBeans。

关于我的问题,他们执行以下操作:

第一的:

@ManagedBean
public class Provider {

    private Event<ProvideEvent> event;

    private static boolean handling = false;
    public provide(@Observes ConsumeEvent consume){
      if(!handling){
        //provide some stuff
        event.fire(new ProvideEvent(ProvidedStuff stuff);
      }
    }
}   

第二:

@ManagedBean
@SessionScoped
public class Consumer {

    private Event<ConsumeEvent> event;

    @PostConstruct
    public void initialize(){
      event.fire(new ConsumeEvent());  
    }

    private static boolean handling = false;
    public consume(@Observes ProvideEvent providedStuff){
      if(!handling){
        //use the provided stuff
      }
    }
}     

这发生在网站被调用时: 1. 消费者被实例化。2. 消费者触发事件。3. Provider 被实例化。4. 调用provide()。5. 实例化一个新的消费者 6. 调用 consume()。

如您所见,我不得不使用布尔“处理”来防止应用程序无限循环。

为什么容器不使用实例化的 SessionScoped ManagedBean?我认为 SessionScoped ManagedBeans 就像 Session 的 Singleton?我想我可以通过以下方式解决这个问题: A:对更改的属性使用静态变量。B:手动实现观察者模式。

但是这里必须有一个更简单的方法!?

4

1 回答 1

1

我相信问题可能是您@PostConstructCustomer.

从javadocs:

该方法必须在类投入使用之前调用。

据我了解,这会导致竞争状况。可能在您的实例完成执行并且容器将其投入服务Provider之前触发第二个事件。因此,它不会收到该事件。不过,我对 Java EE 太缺乏经验,无法就如何防止这种竞争状况给出好的建议。我可能会以一个丑陋的人作为交汇点来解决它。Customerinitialize()SynchronousQueue

附加信息:@Observes如果不存在(正在服务中),则默认创建事件接收器的新实例。这就是创建另一个客户的原因。用于@Observes(notifyObserver = Reception.IF_EXISTS)仅通知正在服务的现有实例。

我认为 SessionScoped ManagedBeans 就像 Session 的 Singleton?

不,它只是定义了对象的生命周期。它并没有真正强制执行会话单例行为。但是,如果在触发第二个事件时它正在服务中,则容器可能更喜欢现有实例。

于 2013-01-15T10:09:14.143 回答