使用会话序列化处理Vaadin中的非序列化Guava EventBus

时间:2016-04-21 12:35:00

标签: java session serialization vaadin guava

我正在创建一个Vaadin应用程序,基于QuickTickets演示应用程序和其他示例,我决定使用Guava的EventBus进行事件处理,因此我保留了一个在UI实例级别引用它。

由于我也使用Spring Boot和DevTools,它可以重新加载应用程序而不需要冷启动,我发现Guava的EventBus不是Serializable,导致java.io.NotSerializableException

如何避免这种情况?

例如:

  1. 有没有办法在Serializable周围制作一个EventBus包装器?它需要保留一个已注册的事件监听器列表,并在会话重新加载时将它们重新注册到EventBus(我想它需要transient EventBus的引用,所以它不会&# 39; t序列化)。
  2. 因为我还是使用Spring,也许我可以使EventBus成为一个用户范围内的Bean?我想我还需要以某种方式处理重新注册的听众。

3 个答案:

答案 0 :(得分:2)

尝试让vaadin在共享会话环境中运行我也不得不面对这个问题。结合Jose的强大的SerializableProxy-annotation和vaadin的spring集成库(也感谢xpoft的另一个实现),似乎可以让它运行。

您可以在此处找到示例应用程序:前端微服务中的https://github.com/khauser/microservices4vaadin

在那里你还可以找到来自快速技术支持仪表板的调整后的EventBus,它可以自动装配/注入,如:

@Autowired
@SerializableProxy
private MyEventBus myEventBus;

答案 1 :(得分:1)

使用spring和vaadin时这是一个常见的问题,因为大多数弹簧单体不是可序列化的(或者根本不应该序列化)。

我编写了一个小型库jdal-aop,允许使用可序列化的代理直接在vaadin UI上注入任何spring bean。

也许你想尝试一下。

答案 2 :(得分:0)

您不应该序列化EventBus,因为它将包含应使用新UI重新创建的UI组件实例。如果你想避免异常,你可以简单地创建一个如你所提到的包装器Serializable类,使该类会话成为范围,并将EventBus放在该类中,标记为瞬态。

如果您根本不想要会话持久性(这是应该轻松复制的无状态应用程序的关键),请将server.session.persistent=false放到application.properties文件中。