How to use Spring services in JSF-managed beans?

。_饼干妹妹 提交于 2019-11-28 06:08:58

问题


JSF is very popular technology in Java world, however, cooperation with Spring is still painfull and requires 'nasty' hacks. I have currently the problem with one of this 'hacks'.

Spring services are injected using the SpringBeanFacesELResolver. It is configured in faces-config.xml:

<application>
    <el-resolver>
        org.springframework.web.jsf.el.SpringBeanFacesELResolver
    </el-resolver>
</application>

The injection of Spring services is very ugly, but it is working:

@ManagedProperty(value="#{customerService}")
CustomerService customerService;

But there are issues. JSF requires from me that the managed bean should be serializable. That means, that the Spring service must also be serializable, or the field should be transient. When the field is transient, the injection is not working (I have null in that field). And making Spring services serializable is in my opinion not a good idea and a potential performance issues - what should happen with Hibernate context, data sources, which all are injected into Spring service?

So, what is the correct and less painfull way of using Spring services withing JSF managed beans?


回答1:


I experienced a lot of issues with org.springframework.web.jsf.el.SpringBeanFacesELResolver, too. Mostly related to unmatching object scopes (Spring has no equivalent to JSF's view scope and conversation scope). Some people also complain about serialization problems.

I successfully applied the solution proposed in this article: http://www.beyondjava.net/blog/integrate-jsf-2-spring-3-nicely/.

In my case, serialization, was not a problem and I was only concerned with bean scopes. I wished JSF to fully manage the backing beans lifecycle without interference with Spring beans lifecycle.

I made JSF managed beans to load the Spring context and autowire themselves to access Spring-managed beans from the JSF context.

I developed the following JSF bean superclass:

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, my concrete JSF backing beans looked like this (I was able to use view scope without problems):

@ManagedBean
@ViewScoped
public class MyBackingBean extends AutowireableManagedBean {

    @Autowired
    private MyDao myDao;


来源:https://stackoverflow.com/questions/13497528/how-to-use-spring-services-in-jsf-managed-beans

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!