JSF Central - Introduction to Spring Faces Part 1
JSF Central

 
 Home 
 
 Products 
 
 Articles & Books 
 
 Resources 
Articles
 
Introduction to Spring Faces Part 1
by Jeremy Grelle
17 Sep 2008 04:45 EDT

Spring Web Flow 2 introduced the Spring Faces module, which provides first-class integration support between JavaServer Faces (JSF) and Spring. This is the first article in a series about Spring Faces. It explains both the JSF-centric and Spring-centric approaches to integrating the two frameworks.


As part of the recent final release of Spring Web Flow 2, along comes the official introduction of the Spring Faces module. This module builds on the foundation of Spring MVC and Spring Web Flow (SWF) to provide first-class integration support between JavaServer Faces (JSF) and Spring. Spring has long included basic JSF integration in its web module, which by itself provides the necessary glue between a typical JSF web layer and a Spring managed business layer. This integration is what we today refer to as the JSF-centric way of integrating the two technologies. Though many applications have been built successfully using this approach, we on the Spring Web team felt that there was still a disconnect between the two, with too many artifacts and too much conceptual overhead to manage easily.

Spring Faces turns the table and approaches the integration from a different angle, with the goal of bringing the strengths of JSF to a Spring-driven web environment. At the same time, it alleviates many of the common frustrations that come with developing a traditional pure JSF web application. Spring Faces pushes the Spring programming model further up the stack, and advocates more of a "turtles all the way down" approach to using JSF with Spring. This is what we refer to as the Spring-centric approach to developing web applications with the JSF UI component model. This article aims to demonstrate the benefits of this approach and why it should appeal to JSF and Spring developers.

JSF and Spring - The perfect combination?

JSF by itself offers great benefits when you are developing rich web applications, especially when they have complex user interactions that stand to benefit from a stateful programming model. Its UI component model is solid and powerful. When applied appropriately, it achieves well its goals of shielding you from the complexities involved in building rich UI controls in a web browser. The ability to declaratively build a rich user interface, combined with the flexible binding of the values of individual controls directly to your domain model through the Unified Expression Language (EL), enables you to quickly build complex web user interfaces without having to worry about the internal mechanics of the components. All of this is achieved with a simple POJO programming model.

Spring is a natural fit and the logical choice for the domain layer of a JSF-fronted application, as it enables a similar POJO programming model. By taking advantage of a few of JSF's many well-defined extension points, it's simple to plug a Spring-powered business layer into a JSF front-end.

JSF-centric integration via EL

In the JSF-centric approach to integration, the JSF controller model is driving the application and JSF managed beans delegate to Spring for business-layer concerns. Spring provides several integration classes that can be selected and used a la carte by configuring them in faces-config.xml. The most widely used of these classes is the DelegatingVariableResolver (and the JSF 1.2 equivalent SpringBeanFacesELResolver). This class effectively makes Spring beans resolvable via EL expressions. The typical usage pattern is to use EL to inject Spring beans into JSF managed beans. For example, if you have the following simple Spring bean defined in your WebApplicationContext:

<bean id="mySpringService" class="com.foo.MySpringServiceImpl">

You can then use EL to inject that service into a JSF managed bean by referencing it in the <managed-bean> definition in faces-config.xml.

<managed-bean> <managed-bean-name>myJsfManagedBean</managed-bean-name> <managed-bean-class>com.foo.MyJsfManagedBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <managed-property> <property-name>mySpringService</property-name> <value>#{mySpringService}</value> </managed-property> </managed-bean>

This results in the Spring managed singleton service getting injected into the JSF managed bean every time an instance of the bean is created by JSF. As of Spring 2.0, where you have the ability to have request and session scoped Spring beans, you can even eliminate the JSF managed beans altogether, and simply rely on the Spring container to instantiate and manage the beans the first time they are referenced via an EL expression.

Does the JSF-centric approach go far enough?

With Spring's simple JSF integration classes, you can smoothly integrate Spring managed services into a JSF-driven front end. But does this go far enough? I would assert that it does not, and that this approach in fact leaves much to be desired. For one, it assumes that the traditional JSF controller model is adequate, when in practice it has proven to have several deficiencies:

  • With it's pull-MVC approach, everything is driven by the rendering of the view, with no convenient points for initialization of the model prior to rendering.
  • The cumbersome navigation model gives little or no feedback when you make a mistake (such as misspelling a navigation outcome) and requires an application restart anytime a rule is added or modified.
  • The validation model doesn't go far enough, as it is focused mainly on individual field-level validation only on the server-side. A convenient way of being able to do client-side field validation and server-side model-level validation without having to navigate the component tree is sorely needed.
  • URL mapping is rather inflexible and the URL is usually a step behind unless you perform a redirect. The redirect support is generally not sufficient, as certain things like FacesMessages do not get preserved across the redirect.
  • Finer-grained scopes in between request and session scope are commonly needed, especially when working with Ajax-based views that fire multiple in-page events.
  • Exception handling capabilities are quite limited, especially if they occur during view rendering (which can often be the case in using the pull-MVC approach).
  • Control logic gets spread throughout JSF managed beans, which can be difficult to unit test and require an application restart anytime changes are made.

JSF's UI component model is solid; it allows rich behavior to be encapsulated and executed within the well-defined boundaries of the JSF component lifecycle. However its controller model is rather limited, especially to someone who is used to the power and flexibility of Spring, Spring MVC, and Spring Web Flow. The JSF-centric approach to integration introduces an extreme amount of conceptual overhead, since you have to continually manage many disparate artifacts, such as faces-config.xml, JSF managed beans, JSF view templates, and all of the components of your Spring-based business layer.

Initially, Spring Web Flow 1.x also attempted to integrate in a JSF-centric way, but this approach proved to have numerous limitations. It required yet more JSF artifacts to be chosen a la carte and manually added to the faces-config.xml in order to function properly, introducing further conceptual complexity. This approach was by no means agile.

We decided that what would be ideal was if the strengths of JSF's UI component model could be integrated into a Spring environment, while pushing the Spring programming model further up the stack for a more Spring-centric approach. If you could let Spring be in control of the entire request, you could have a consistent programming and configuration model throughout the entire application. You could also take full advantage of Spring MVC's flexible routing infrastructure and Spring Web Flow 2.x's agile stateful controller model, which is a natural fit with stateful JSF views. This is the motivation for the creation of Spring Faces and its addition to the Spring portfolio.



RSS feed(all feeds)

The Editor's Desk
Podcasts
Inside Facelets
In the Trenches

Site version 1.83  Report web site problems

Copyright (C) 2003-2014 Virtua, Inc. All Rights Reserved. Java, JavaServer Faces, and all Java-based marks are trademarks or registered trademarks of Oracle Corporation. in the United States and other countries. Virtua, Inc. is independent of Oracle Corporation. All other trademarks are the sole property of their respective owners.