1

JSF 是 Java 世界中非常流行的技术,然而,与 Spring 的合作仍然很痛苦,并且需要“讨厌”的 hack。我目前遇到这种“黑客”之一的问题。

Spring 服务是使用SpringBeanFacesELResolver. 它配置在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 一起使用的正确且不那么痛苦的方法是什么?

4

1 回答 1

1

我也遇到了很多关于 org.springframework.web.jsf.el.SpringBeanFacesELResolver 的问题。主要与不匹配的对象范围有关(Spring 没有等效于 JSF 的视图范围和会话范围)。有些人还抱怨序列化问题。

我成功应用了本文提出的解决方案:http ://www.beyondjava.net/blog/integrate-jsf-2-spring-3-nicely/ 。

就我而言,序列化不是问题,我只关心 bean 范围。我希望 JSF 能够完全管理支持 bean 的生命周期,而不会干扰 Spring 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;
于 2015-08-12T01:03:34.803 回答