Spring into Seam, Part 1: Build a Spring-Seam hybrid component

Which is better, Seam or Spring? Learn why you don't have to choose

1 2 3 4 5 6 Page 2
Page 2 of 6

Bootstrapping Spring and Seam simultaneously

Both Seam and Spring provide servlet context listeners that are used to bootstrap the respective containers. If you register both listeners in the same Web application, then the associated containers are loaded based on the relative order of the listener stanzas in the web.xml descriptor. Instead of hedging a bet that load order alone can guarantee a successful startup, it is better to give one container the responsibility of booting the other. Seam steps forward and offers the ContextLoader (<spring:context-loader>) component to handle this task. This built-in Seam component performs the same work as Spring's ContextLoaderListener, so the Spring container won't even recognize that it is being started through a different mechanism. If you are going to be using Spring and Seam together in an application, I strongly recommend that you leverage this boot configuration.

The ContextLoader component allows one or more Spring configuration file locations to be specified in the config-locations property of the <spring:context-loader> tag, defined in the Seam component descriptor. The config-locations property is a String array and can be configured in the typical way for a multi-valued component property. Mimicking the behavior of the ContextLoaderListener, if no configuration locations are specified on <spring:context-loader>, the Spring configuration is assumed to be present at the resource path /WEB-INF/applicationContext.xml. With Seam assuming control of the Spring startup, the contextConfigLocation servlet context parameter in the web.xml descriptor is no longer needed.

Here are two examples of the ContextLoader configuration in the Seam component descriptor, /WEB-INF/components.xml (or /META-INF/components.xml). Listing 1 uses a single Spring configuration file in a non-default location.

Listing 1. Loading a single Spring configuration file

<spring:context-loader config-locations="/WEB-INF/spring-beans.xml"/>

Listing 2 divides the Spring configuration files up into layers and positions them on the classpath rather than in the Web configuration directory.

Listing 2. Loading multiple Spring configuration files

<spring:context-loader
  config-locations="classpath:spring-beans-persistence.xml
classpath:spring-beans-service.xml"/>

As Listing 3 illustrates, you could also break the config-locations property value up into child elements.

Listing 3. Multiple Spring configuration files, itemized explicitly

<spring:context-loader>
  <spring:config-locations>
    <value>classpath:spring-beans-persistence.xml</value>
    <value>classpath:spring-beans-service.xml</value>
  </spring:config-locations>
</spring:context-loader>

To use this component definition, you must register the XML namespace for the Spring module at the top of the Seam component descriptor, as shown in Listing 4. Note that the namespaces shown here are different from the XML namespaces used in your Spring configuration file.

Listing 4. Registering the Spring XML namespace

<components xmlns="http://jboss.com/products/seam/components"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:spring="http://jboss.com/products/seam/spring"
  xsi:schemaLocation="
    http://jboss.com/products/seam/components
    http://jboss.com/products/seam/components-2.0.xsd
    

http://jboss.com/products/seam/spring

http://jboss.com/products/seam/spring-2.0.xsd"

> <!-- component declarations --> </components>

Putting Seam in charge of loading the Spring container also makes it easy to integration-test Seam applications that rely on Spring beans. When Seam's integration test infrastructure loads the Seam container, it transitively loads the Spring container. Seam's integration test infrastructure is activated by writing tests that extend the SeamTest base class.

Using Seam and Spring in the same application goes beyond just divvying up your managed objects between two containers. What this integration affords you is the possibility of promoting Spring beans into Seam components at the level of the configuration metadata to form a Spring-Seam hybrid component, which you'll learn about in the next section. The simultaneous loading of the two containers permits this type of integration because the Seam container is active and ready to register additional components at the time the Spring configuration file is parsed.

1 2 3 4 5 6 Page 2
Page 2 of 6