One of the main benefits that the Spring Framework offers is the ability to choose. In a general sense, Spring doesn't force you to use or buy any particular architecture, technology, or methodology (although it certainly has some recommendations regarding one or another). This freedom to choose the architecture, technology or methodology that best suits the developer or his development team is perhaps most evident in the web domain, where Spring offers its own web frameworks (Spring MVC and Spring WebFlux) but at the same time supports integration with a number of popular third-party web frameworks.
General configuration
Before diving into the integration features of each supported web framework, let's first look at the general Spring configuration, which is not specific to any one web framework. (This section applies equally to native variants of the Spring web framework.)
One of the concepts (for lack of a better word) supported by the Spring lightweight application model is layered
architecture. Remember that in a "classic" layered architecture, the web tier is just one of many. It serves as one
of the entry points into a server-side application and delegates authority to service objects (facades) that are
defined at the service layer to handle specific (and presentation-independent) business use cases. In Spring, these
are service objects, any other business objects, data access objects, etc. exist in a separate "business context"
that does not contain web or presentation tier objects (presentation objects such as Spring MVC controllers are
typically configured in a separate "presentation tier context"). This section details how you can configure a Spring
container (WebApplicationContext
) containing all the "business beans" of your application.
Getting specific, all you need to do is declare ContextLoaderListener
in the standard Java EE servlet file web.xml
of your web application and add a contextConfigLocation
section
(in the same file), which specifies which set of Spring XML configuration files to load.
Consider the following <listener/>
configuration:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Next, consider the following configuration <context-param/>
:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
If you do not specify the contextConfigLocation
context parameter, the
ContextLoaderListener
will look for the /WEB-INF/applicationContext.xml
file to load.
After loading the context files, Spring creates an object WebApplicationContext
based on bean definitions and stores it in the ServletContext
of the web application.
All Java web frameworks are built on top of the Servlet API, so you can use the following code snippet to access this
"business context" ApplicationContext
created by the ContextLoaderListener
.
The following example shows how to get the WebApplicationContext
:
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
Class WebApplicationContextUtils
is for convenience so you don't have to remember
the name of the ServletContext
attribute. Its getWebApplicationContext()
method returns
null
if the object under the key
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
does not exist. To avoid getting NullPointerExceptions
in your application, it is better to use the getRequiredWebApplicationContext()
method. This method
throws an exception if ApplicationContext
is missing.
Once you have a reference to the WebApplicationContext
, you can retrieve beans by their name or type.
Most developers obtain beans by name and then cast them to one of the implemented interfaces.
Fortunately, most of the frameworks described in this section have easier ways to find beans. Not only do they make it easy to get beans from a Spring container, but they also allow you to use dependency injection in their controllers. Each section of the web framework describes specific integration strategies in more detail.
JSF
JavaServer Faces (JSF) is a standard component-based, event-driven web user interface framework developed as part of the JCP process. It is an official part of the generic Java EE specification, but can also be used separately, for example by embedding Mojarra or MyFaces in Tomcat.
Please note that recent versions of JSF have become tightly coupled with the CDI framework in application servers, and some new JSF features only work in such an environment. JSF support in Spring is no longer actively developed and is mainly used for migration purposes when modernizing older applications based on JSF.
The key element of Spring's integration with JSF is the ELResolver
mechanism of the JSF specification.
5.2.1. Spring Bean Recognizer
SpringBeanFacesELResolver
is a JSF-compatible implementation of ELResolver
that integrates
with the standard Unified Expression Language (Unified EL) used in JSF and JSP. It delegates authority first to the
Spring "business context" WebApplicationContext and then to the default resolver of the underlying JSF
implementation.
From a configuration perspective, you can define SpringBeanFacesELResolver
in the faces-context.xml
JSF specification file, as shown in the following example:
<faces-config>
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
...
</application>
</faces-config>
5.2.2. Using FacesContextUtils
Custom ELResolver
works great when mapping properties to beans in faces-config.xml
, but
sometimes you may need to explicitly capture the bean. Class FacesContextUtils
makes this task easier. It is similar to WebApplicationContextUtils
,
except that it accepts a FacesContext
parameter rather than a ServletContext
.
The following example shows how to use FacesContextUtils
:
ApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());
Apache Struts 2.x
The Struts framework, created by Craig McClanahan, is an open source project based on the Apache Software Foundation. At the time, it greatly simplified the JSP/Servlet programming paradigm and won over many developers who were using proprietary frameworks. It simplified the programming model, was open source (meaning free), and had a large community, allowing the project to grow and become popular among Java web developers.
As a successor to the original Struts 1.x, check out Struts 2.x and the one provided in Struts a plugin for Spring designed for native integration with Spring.
Apache Tapestry 5.x
Tapestry is “a component-based framework for building dynamic, robust, scalable Java web applications” .
Although Spring has its own powerful web tier, building an enterprise Java application using a combination of Tapestry for the web UI and a Spring container for the lower layers offers a number of unique benefits.
For more information, see the dedicated Tapestry integration module for Spring .
Additional sources
The following links provide additional resources for the various web frameworks discussed in this chapter.