【问题标题】:Java EE Firing an Event creates a new InstanceJava EE 触发事件会创建一个新实例
【发布时间】:2013-01-02 16:44:30
【问题描述】:

我有两个 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. 调用 consumer()。

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

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

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

【问题讨论】:

    标签: java jakarta-ee observer-pattern managed-bean session-scope


    【解决方案1】:

    我相信问题可能是您在 Customer@PostConstruct 方法中触发了事件。

    来自 javadocs:

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

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

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

    我认为 SessionScoped ManagedBeans 就像 Session 的 Singleton?

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

    【讨论】:

    • 感谢您的帮助,我现在通过自己实现观察者模式解决了这个问题。但如果您的方法有效,我会尝试并回复您。
    • 我终于找到时间重现该问题 ;) 你是对的,它确实会产生从 @PostConstruct 方法触发事件的问题。再次感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 2020-01-01
    • 2017-05-11
    相关资源
    最近更新 更多