JSF and Spring Integration
February 6th, 2007 . by James AdamsIn a perfect world, all of my Java-based projects would be using JSF 1.2 and Spring 2.0. The managed beans in my JSF FacesContext would blend nicely with my Spring-managed beans, and the scopes of all would interact smoothly. Unfortunately, this is not a perfect world, and while I strive to keep my projects in the proper technology stack, I do not always have control over the initial state of a client’s project. One of my current projects is a fantastic example of this. We are using JSF and Spring, but the JSF implementation is Apache MyFaces 1.0.9, and the Spring version is 1.2. The managed beans in the two technologies do not blend together nicely, and although there is a project that would seem to provide a solution (JSF-Spring), documentation is sparse and the required version numbers do not match up. The big obstacle here is that Spring (even version 1.2) provides some very nice annotational transaction management that the current codebase is using to great advantage. Unfortunately, in order for Spring to manage the transactions, the beans must be declared within the Spring Application Context. This leaves my JSF-managed web controllers out in the cold, and me looking for an elegent solution. My first attempt lead me to Spring’s DelegatingVariableResolver class, which provides the ability to refer to beans defined in the Spring Application Context through JSF value-binding expressions. I begin by creating a single GatewayController class that has a property for each of the web controllers that have already been created. I then move the web controllers from the JSF faces-config.xml file into my Spring applicationContext.xml file. After adding a <managed-bean> definition in faces-config.xml for the GatewayController class and binding the managed properties to the Spring beans, everything seems to be reachable from the JSF code. Unfortunately, Spring 1.2 provides only two bean scopes: singleton and prototype. These correspond to the JSF application and none scopes, respectively. But what about the session and request scopes that are available in JSF? It seems that there could be some trouble mixing certain scopes together. For example, what happens if I create a session-scoped JSF bean that references a singleton-scoped Spring bean? Logically it seems like I would get a new copy of the JSF bean for every session, but each would refer to the same singleton copy of the Spring bean. Given that a session-scoped bean would typically be declared only if the bean held session-specific data, this does not seem like a good solution. The idealist in my immediately yells out that I should upgrade the entire web application to Spring 2.0 (which supports the additional scopes that I want for JSF), but the pragmatist reminds me that I am dealing with an extremely large web application, and the ramifications of such an upgrade could be staggering in other parts of the system. I do not yet have a complete solution for this problem, but I will post more as things progress. If there are any suggestions out there, let’s have them…