blob: 5e55ff67b9b44d5013798a515a3c1683379a3645 [file] [log] [blame]
----
Tapestry/Spring Integration
----
Tapestry/Spring Integration
Provides integration between Tapestry and Spring, allowing beans defined by Spring to be injected into Tapestry IoC services, and into
Tapestry components.
Version
This module is compiled and tested against Spring 1.2.8. However, Spring 2.0 is fully backwards compatible to Spring 1.2.8.
This module uses the Maven scope "provided" for the dependencies on Spring. This means that in your own POM, you will need to specify your own
dependency to Spring, including the correct version. Example:
+---+
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>1.2.8</version>
</dependency>
+----+
With the default Maven scope, the Spring JARs and dependencies will be packaged into your application's WAR file.
Usage
The integration is designed to be a very thin layer on top of Spring's normal configuration for a web application.
Detailed instructions are available in the
{{{http://static.springframework.org/spring/docs/1.2.x/reference/beans.html#context-create}Spring 1.2.x documentation}}.
* web.xml changes
The short form is that you must make two small changes to your application's web.xml.
First, a special filter is used in replace of the standard TapestryFilter:
+---+
<filter>
<filter-name>app</filter-name>
<!-- Special filter that adds in a T5 IoC module derived from the Spring WebApplicationContext. -->
<filter-class>org.apache.tapestry5.spring.TapestrySpringFilter</filter-class>
</filter>
+---+
Secondly, you must add the normal Spring configuration, consisting of a \<listener\> element,
and (optionally) a \<context-param\> identifying which Spring bean configuration file(s) to load:
+---+
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
+---+
The \<context-param\> lists the Spring bean configuration file. It is optional and defaults to just /WEB-INF/applicationContext.xml if omitted.
The ContextLoaderListener is responsible for reading the bean configuration file (or files) and storing the result in the application context, where
the Tapestry-Spring integration code can make use of it.
* Injecting beans
Inside your component classes, you may use the
{{{http://tapestry.apache.org/tapestry5/tapestry-core/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html}Inject}} annotation. Typically, just the field
type is sufficient to identify the Spring bean to inject:
+----+
@Inject
private UserDAO userDAO;
+----+
If you have multiple beans that implement the same interface (for instance, if you have wrapped your bean using a transaction interceptor), you must disambiguate. The easiest way
to accomplish this is to add a
{{{http://tapestry.apache.org/tapestry5/tapestry-core/apidocs/org/apache/tapestry5/annotations/Service.html}Service}}
annotation to identify the name of the
Spring bean:
+----+
@Inject
@Service("UserDAO")
private UserDAO userDAO;
+----+
Injection of Spring beans via service builder methods or autobuilding occurs just the same: the Spring beans masquerade as Tapestry IoC services and all is well.
Case Insensitivity
Spring beans names are treated exactly as Tapestry IoC service ids. Since service ids are case insensitive, access to Spring beans by bean name will also
be case insensitive.
WebApplicationContext Service
The Spring WebApplicationContext is also added as a service, in addition to any services defined within the context.
Limitations
The names of beans are obtained at application start up. If new beans are programattically added to the Spring application context at runtime,
these will not be visible for injection.
Only the bean <name> is used, not any of the bean's <aliases>.
No check is made for name clashes that would occur when two beans have names that differ only in terms of capitalization. If you're going to go around naming beans "userDAO" and "UserDao",
you're just asking for trouble.
Non-singleton beans are not handled properly. Tapestry will request the beans from the application context in a manner unsuitable for their lifecycle.
For the moment, you should consider the non-singleton beans to be not-injectable. Instead, inject the WebApplicationContext service and
obtain the non-singleton beans as needed.