讨论:如何处理SessionScope和序列化自己的关系?
事情的起因是这样的:我想使用JSF2.0的ViewScope的MangedBean作为一个编辑界面的backing bean,但是发现它竟然要求这个bean必须要求支持序列化——因为ViewScope是通过把状态保存在ViewRoot上来实现的,这又依赖于StateManager,它在保存状态时需要序列化。本来让这个bean实现序列化接口就可以了,不过我这个bean可能还有一个属性是一个Spring的bean,难道我让这个Spring的bean也要支持序列化吗?
?
是的,问题的关键是序列化保存状态的问题引起的,其实SessionScope也会有这个问题——如果需要支持Session的复制的话。看来这不是JSF特有的问题,Spring中应该也有相似的问题,果不其然,我在Spring的论坛里找到了一个帖子:
?
http://forum.springsource.org/showthread.php?t=56569
?
So I'd be very grateful if you guys comment on my problem/ideas.?
如果你在Spring的SessionScope的bean中引用SingletonScoped的bean的话也会存在同样的问题。上面的帖子给出两种可能的解决方案,不过并不完美。或许本不该这么用?避免这么使用吗?
?
回到JSF,有时候这么用有很方便,我想出两种解决方案:
?
在JSF的SessionScope和ViewScope的managed bean中不注入Spring的bean,这两种Scope的managed bean只保存一般的属性和领域对象。处理界面的操作的部分放入另一个RequestScope的managed bean中,并在这个RequestScope的managedbean中引用SessionScope或ViewScope的managed bean。缺点就是无端多出几个manged bean来。不使用IoC的方式注入Spring的bean到managed bean中,而是每次通过Spring的Application Context去getBean,这样manged bean中不存在对Spring bean的引用,序列化就不成问题了。缺点就是可能牺牲一些代码的优雅性,Mock测试mangaged bean的时候也不太方便。不过一般很少mock测试manged bean。
还有更好的解决方案吗?
?
最近开到Gavin King发表的一个评论上说使用JSF2.0,EJB和CDI的时候不需要考虑这个序列化的问题,也许JSF和EJB,CDI结合的更完美些,毕竟都是JEE的标准。
?
1 楼 yanhua 2010-07-17 ViewScope出现不能序列化的问题是因为:<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
设成server就没问题了,不过如果集群环境下session复制是不是还有问题?