JSF是Java世界中非常流行的技术,然而,与Spring的合作仍然很痛苦,需要“讨厌”的黑客攻击。我目前遇到了其中一个'黑客'的问题。
使用SpringBeanFacesELResolver
注入Spring服务。它在faces-config.xml
:
<application>
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
</application>
注入Spring服务非常难看,但它正在运行:
@ManagedProperty(value="#{customerService}")
CustomerService customerService;
但有问题。 JSF要求我将托管bean序列化。这意味着,Spring服务也必须是可序列化的,或者字段应该是瞬态的。当字段是瞬态时,注入不起作用(我在该字段中为null)。在我看来,使Spring服务可序列化并不是一个好主意和潜在的性能问题 - Hibernate上下文,数据源应该发生什么,这些都被注入到Spring服务中?
那么,使用Spring服务和JSF托管bean的正确和不那么痛苦的方法是什么?
答案 0 :(得分:1)
我在org.springframework.web.jsf.el.SpringBeanFacesELResolver中遇到了很多问题。主要与不匹配的对象作用域相关(Spring没有与JSF的视图作用域和对话作用域相当)。有些人还抱怨序列化问题。
我成功应用了本文中提出的解决方案:http://www.beyondjava.net/blog/integrate-jsf-2-spring-3-nicely/。
在我的情况下,序列化,不是问题,我只关心bean范围。我希望JSF能够在不干扰Spring bean生命周期的情况下全面管理支持bean的生命周期。
我创建了JSF托管bean来加载Spring上下文并自动自动从JSF上下文访问Spring托管的bean。
我开发了以下JSF bean超类:
public abstract class AutowireableManagedBean {
protected AutowireCapableBeanFactory ctx;
@PostConstruct
protected void init() {
logger.debug("init");
ctx = WebApplicationContextUtils
.getWebApplicationContext(
(ServletContext) FacesContext.getCurrentInstance()
.getExternalContext().getContext())
.getAutowireCapableBeanFactory();
// The following line does the magic
ctx.autowireBean(this);
}
...
}
然后,我的具体JSF支持bean看起来像这样(我能够毫无问题地使用视图范围):
@ManagedBean
@ViewScoped
public class MyBackingBean extends AutowireableManagedBean {
@Autowired
private MyDao myDao;