6
votes

I just introduced Spring in a JSF web application, and now I'm feeling tempted to turn my JSF managed beans into Spring beans by moving these beans to the contextConfigLocation XML file (specifying org.springframework.web.jsf.el.SpringBeanFacesELResolver in faces-config.xml) instead of having the beans in the faces-config.xml file.

I see a lot of advantages if I move to Spring beans (like getting dependency injection functionality) compared against JSF beans so I hardly can argue against moving to Spring beans, but I would like to hear from others what issues I may face if I do this, or what is the best practice for this case.

2

2 Answers

5
votes

The only major issue may be that you're tight-coupling JSF with Spring and that your JSF views/models may not be reuseable anymore without Spring. The only feasible alternative would be upgrading to JSF 2.0 / Java EE 6 and make use of Java EE 6 provided dependency injection facilities instead of relying on a 3rd party DI framework. On the other hand, the current advantages are sound. You can just do so.

2
votes

Don't move JSF managed beans to Spring beans. JSF and Spring beans lifecycles (scopes) do not match completely. For instance, view scope and conversation scope are missing in Spring Framework.

Instead, keep JSF backing beans as JSF-managed beans and autowire Spring beans onto them.

Define an abstract superclass for JSF backing beans like this:

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);
    }
   ...
}

Then, make your backing beans extend that superclass and you will be able to autowire Spring beans and have make use of JSF-specific view scope:

@ManagedBean
@ViewScoped
public class MyBackingBean extends AutowireableManagedBean {

    @Autowired
    private MyDao myDao;

Further info in this article: http://www.beyondjava.net/blog/integrate-jsf-2-spring-3-nicely/