如何在JSF托管的bean中使用Spring服务?

时间:2012-11-21 16:19:56

标签: spring jsf service managed-bean serializable

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的正确和不那么痛苦的方法是什么?

1 个答案:

答案 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;