664 lines
32 KiB
XML
664 lines
32 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
|
<section id="context-introduction">
|
|
<title>Additional Capabilities of the
|
|
<interfacename>ApplicationContext</interfacename></title>
|
|
|
|
<!-- MLP: Beverly to review paragraph and list -->
|
|
|
|
<para>As was discussed in the chapter introduction, the
|
|
<literal>org.springframework.beans.factory</literal> package provides basic
|
|
functionality for managing and manipulating beans, including in a
|
|
programmatic way. The <literal>org.springframework.context</literal> package
|
|
adds the <ulink
|
|
url="http://static.springframework.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/ApplicationContext.html"
|
|
><interfacename>ApplicationContext</interfacename></ulink> interface, which
|
|
extends the <interfacename>BeanFactory</interfacename> interface, in
|
|
addition to extending other interfaces to provide additional functionality
|
|
in a more <emphasis>application framework-oriented style</emphasis>. Many
|
|
people use the <interfacename>ApplicationContext</interfacename> in a
|
|
completely declarative fashion, not even creating it programmatically, but
|
|
instead relying on support classes such as
|
|
<classname>ContextLoader</classname> to automatically instantiate an
|
|
<interfacename>ApplicationContext</interfacename> as part of the normal
|
|
startup process of a J2EE web application.</para>
|
|
|
|
<para>To enhance <interfacename>BeanFactory</interfacename> functionality in a
|
|
more framework-oriented style the context package also provides the
|
|
following functionality:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>Access to messages in i18n-style</emphasis>, through the
|
|
<interfacename>MessageSource</interfacename> interface.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><emphasis>Access to resources</emphasis>, such as URLs and files,
|
|
through the <interfacename>ResourceLoader</interfacename>
|
|
interface.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><emphasis>Event publication</emphasis> to beans implementing the
|
|
<interfacename>ApplicationListener</interfacename> interface, through
|
|
the use of the <interfacename>ApplicationEventPublisher</interfacename>
|
|
interface.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><emphasis>Loading of multiple (hierarchical) contexts</emphasis>,
|
|
allowing each to be focused on one particular layer, such as the web
|
|
layer of an application, through the
|
|
<interfacename>HierarchicalBeanFactory</interfacename> interface.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<section id="context-functionality-messagesource">
|
|
<title>Internationalization using
|
|
<interfacename>MessageSource</interfacename></title>
|
|
|
|
<!-- MLP: Beverly to review this paragraph -->
|
|
|
|
<para>The <interfacename>ApplicationContext</interfacename> interface
|
|
extends an interface called <interfacename>MessageSource</interfacename>,
|
|
and therefore provides internationalization (i18n) functionality. Spring
|
|
also provides the interface
|
|
<classname>HierarchicalMessageSource</classname>, which can resolve
|
|
messages hierarchically. Together these interfaces provide the foundation
|
|
upon which Spring effects message resolution. The methods defined on these
|
|
interfaces include:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><methodname>String getMessage(String code, Object[] args, String
|
|
default, Locale loc)</methodname>: The basic method used to retrieve a
|
|
message from the <interfacename>MessageSource</interfacename>. When no
|
|
message is found for the specified locale, the default message is
|
|
used. Any arguments passed in become replacement values, using the
|
|
<interfacename>MessageFormat</interfacename> functionality provided by
|
|
the standard library.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><methodname>String getMessage(String code, Object[] args, Locale
|
|
loc)</methodname>: Essentially the same as the previous method, but
|
|
with one difference: no default message can be specified; if the
|
|
message cannot be found, a
|
|
<classname>NoSuchMessageException</classname> is thrown.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para><methodname>String getMessage(MessageSourceResolvable resolvable,
|
|
Locale locale)</methodname>: All properties used in the preceding
|
|
methods are also wrapped in a class named
|
|
<interfacename>MessageSourceResolvable</interfacename>, which you can
|
|
use with this method.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>When an <interfacename>ApplicationContext</interfacename> is loaded,
|
|
it automatically searches for a
|
|
<interfacename>MessageSource</interfacename> bean defined in the context.
|
|
The bean must have the name <literal>messageSource</literal>. If such a
|
|
bean is found, all calls to the preceding methods are delegated to the
|
|
message source. If no message source is found, the
|
|
<interfacename>ApplicationContext</interfacename> attempts to find a
|
|
parent containing a bean with the same name. If it does, it uses that bean
|
|
as the <interfacename>MessageSource</interfacename>. If the
|
|
<interfacename>ApplicationContext</interfacename> cannot find any source
|
|
for messages, an empty <classname>DelegatingMessageSource</classname> is
|
|
instantiated in order to be able to accept calls to the methods defined
|
|
above.</para>
|
|
|
|
<para>Spring provides two <interfacename>MessageSource</interfacename>
|
|
implementations, <classname>ResourceBundleMessageSource</classname> and
|
|
<classname>StaticMessageSource</classname>. Both implement
|
|
<interfacename>HierarchicalMessageSource</interfacename> in order to do
|
|
nested messaging. The <classname>StaticMessageSource</classname> is rarely
|
|
used but provides programmatic ways to add messages to the source. The
|
|
<classname>ResourceBundleMessageSource</classname> is shown in the
|
|
following example:</para>
|
|
|
|
<programlisting language="xml"><beans>
|
|
<bean id="messageSource"
|
|
class="org.springframework.context.support.ResourceBundleMessageSource">
|
|
<property name="basenames">
|
|
<list>
|
|
<value>format</value>
|
|
<value>exceptions</value>
|
|
<value>windows</value>
|
|
</list>
|
|
</property>
|
|
</bean>
|
|
</beans></programlisting>
|
|
|
|
<para>In the example it is assumed you have three resource bundles defined
|
|
in your classpath called <literal>format</literal>,
|
|
<literal>exceptions</literal> and <literal>windows</literal>. Any request
|
|
to resolve a message will be handled in the JDK standard way of resolving
|
|
messages through ResourceBundles. For the purposes of the example, assume
|
|
the contents of two of the above resource bundle files are...</para>
|
|
|
|
<programlisting language="java"><lineannotation># in format.properties</lineannotation>
|
|
message=Alligators rock!</programlisting>
|
|
|
|
<programlisting language="java"><lineannotation># in exceptions.properties</lineannotation>
|
|
argument.required=The '{0}' argument is required.</programlisting>
|
|
|
|
<para>A program to execute the <classname>MessageSource</classname>
|
|
functionality is shown in the next example. Remember that all
|
|
<classname>ApplicationContext</classname> implementations are also
|
|
<classname>MessageSource</classname> implementations and so can be cast to
|
|
the <classname>MessageSource</classname> interface.</para>
|
|
|
|
<programlisting language="java">public static void main(String[] args) {
|
|
MessageSource resources = new ClassPathXmlApplicationContext("beans.xml");
|
|
String message = resources.getMessage("message", null, "Default", null);
|
|
System.out.println(message);
|
|
}</programlisting>
|
|
|
|
<para>The resulting output from the above program will be...</para>
|
|
|
|
<programlisting>Alligators rock!</programlisting>
|
|
|
|
<para>So to summarize, the <classname>MessageSource</classname> is defined
|
|
in a file called <literal>beans.xml</literal>, which exists at the root of
|
|
your classpath. The <literal>messageSource</literal> bean definition
|
|
refers to a number of resource bundles through its
|
|
<literal>basenames</literal> property. The three files that are passed in
|
|
the list to the <literal>basenames</literal> property exist as files at
|
|
the root of your classpath and are called
|
|
<literal>format.properties</literal>,
|
|
<literal>exceptions.properties</literal>, and
|
|
<literal>windows.properties</literal> respectively.</para>
|
|
|
|
<para>The next example shows arguments passed to the message lookup; these
|
|
arguments will be converted into Strings and inserted into placeholders in
|
|
the lookup message.</para>
|
|
|
|
<programlisting language="xml"><beans>
|
|
|
|
<lineannotation><!-- this <interfacename>MessageSource</interfacename> is being used in a web application --></lineannotation>
|
|
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
|
|
<property name="basename" value="test-messages"/>
|
|
</bean>
|
|
|
|
<lineannotation><!-- lets inject the above <interfacename>MessageSource</interfacename> into this POJO --></lineannotation>
|
|
<bean id="example" class="com.foo.Example">
|
|
<property name="messages" ref="messageSource"/>
|
|
</bean>
|
|
|
|
</beans></programlisting>
|
|
|
|
<programlisting language="java">public class Example {
|
|
|
|
private MessageSource messages;
|
|
|
|
public void setMessages(MessageSource messages) {
|
|
this.messages = messages;
|
|
}
|
|
|
|
public void execute() {
|
|
String message = this.messages.getMessage("argument.required",
|
|
new Object [] {"userDao"}, "Required", null);
|
|
System.out.println(message);
|
|
}
|
|
|
|
}</programlisting>
|
|
|
|
<para>The resulting output from the invocation of the
|
|
<methodname>execute()</methodname> method will be...</para>
|
|
|
|
<programlisting>The userDao argument is required.</programlisting>
|
|
|
|
<para>With regard to internationalization (i18n), Spring's various
|
|
<classname>MessageResource</classname> implementations follow the same
|
|
locale resolution and fallback rules as the standard JDK
|
|
<classname>ResourceBundle</classname>. In short, and continuing with the
|
|
example <literal>messageSource</literal> defined previously, if you want
|
|
to resolve messages against the British (en-GB) locale, you would create
|
|
files called <literal>format_en_GB.properties</literal>,
|
|
<literal>exceptions_en_GB.properties</literal>, and
|
|
<literal>windows_en_GB.properties</literal> respectively.</para>
|
|
|
|
<para>Typically, locale resolution is managed by the surrounding environment
|
|
of the application. In this example, the locale against which (British)
|
|
messages will be resolved is specified manually.</para>
|
|
|
|
<programlisting><lineannotation># in exceptions_en_GB.properties</lineannotation>
|
|
argument.required=Ebagum lad, the '{0}' argument is required, I say, required.</programlisting>
|
|
|
|
<programlisting language="java">public static void main(final String[] args) {
|
|
MessageSource resources = new ClassPathXmlApplicationContext("beans.xml");
|
|
String message = resources.getMessage("argument.required",
|
|
new Object [] {"userDao"}, "Required", Locale.UK);
|
|
System.out.println(message);
|
|
}</programlisting>
|
|
|
|
<para>The resulting output from the running of the above program will
|
|
be...</para>
|
|
|
|
<programlisting>Ebagum lad, the 'userDao' argument is required, I say, required.</programlisting>
|
|
|
|
<para>You can also use the <classname>MessageSourceAware</classname>
|
|
interface to acquire a reference to any
|
|
<classname>MessageSource</classname> that has been defined. Any bean that
|
|
is defined in an <classname>ApplicationContext</classname> that implements
|
|
the <classname>MessageSourceAware</classname> interface is injected with
|
|
the application context's <classname>MessageSource</classname> when the
|
|
bean is created and configured.</para>
|
|
|
|
<note>
|
|
<para><emphasis>As an alternative to
|
|
<classname>ResourceBundleMessageSource</classname>, Spring provides a
|
|
<classname>ReloadableResourceBundleMessageSource</classname> class. This
|
|
variant supports the same bundle file format but is more flexible than
|
|
the standard JDK based
|
|
<classname>ResourceBundleMessageSource</classname>
|
|
implementation.</emphasis> In particular, it allows for reading files
|
|
from any Spring resource location (not just from the classpath) and
|
|
supports hot reloading of bundle property files (while efficiently
|
|
caching them in between). Check out the
|
|
<classname>ReloadableResourceBundleMessageSource</classname> javadoc for
|
|
details.</para>
|
|
</note>
|
|
</section>
|
|
|
|
<section id="context-functionality-events">
|
|
<title>Standard and Custom Events</title>
|
|
|
|
<para>Event handling in the
|
|
<interfacename>ApplicationContext</interfacename> is provided through the
|
|
<classname>ApplicationEvent</classname> class and
|
|
<interfacename>ApplicationListener</interfacename> interface. If a bean
|
|
that implements the <interfacename>ApplicationListener</interfacename>
|
|
interface is deployed into the context, every time an
|
|
<classname>ApplicationEvent</classname> gets published to the
|
|
<interfacename>ApplicationContext</interfacename>, that bean is notified.
|
|
Essentially, this is the standard <emphasis>Observer</emphasis> design
|
|
pattern. Spring provides the following standard events:</para>
|
|
|
|
<table id="beans-ctx-events-tbl">
|
|
<title>Built-in Events</title>
|
|
|
|
<tgroup cols="2">
|
|
<colspec colname="c1" colwidth="2*"/>
|
|
|
|
<colspec colname="c2" colwidth="5*"/>
|
|
|
|
<thead>
|
|
<row>
|
|
<entry>Event</entry>
|
|
|
|
<entry>Explanation</entry>
|
|
</row>
|
|
</thead>
|
|
|
|
<tbody>
|
|
<row>
|
|
<entry><classname>ContextRefreshedEvent</classname></entry>
|
|
|
|
<entry>Published when the
|
|
<interfacename>ApplicationContext</interfacename> is initialized
|
|
or refreshed, for example, using the
|
|
<methodname>refresh()</methodname> method on the
|
|
<interfacename>ConfigurableApplicationContext</interfacename>
|
|
interface. "Initialized" here means that all beans are loaded,
|
|
post-processor beans are detected and activated, singletons are
|
|
pre-instantiated, and the
|
|
<interfacename>ApplicationContext</interfacename> object is ready
|
|
for use. As long as the context has not been closed, a refresh can
|
|
be triggered multiple times, provided that the chosen
|
|
<interfacename>ApplicationContext</interfacename> actually
|
|
supports such "hot" refreshes. For example,
|
|
<classname>XmlWebApplicationContext</classname> supports hot
|
|
refreshes, but <classname>GenericApplicationContext</classname>
|
|
does not.</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><classname>ContextStartedEvent</classname></entry>
|
|
|
|
<entry>Published when the
|
|
<interfacename>ApplicationContext</interfacename> is started,
|
|
using the <methodname>start()</methodname> method on the
|
|
<interfacename>ConfigurableApplicationContext</interfacename>
|
|
interface. "Started" here means that all
|
|
<interfacename>Lifecycle</interfacename> beans receive an explicit
|
|
start signal. Typically this signal is used to restart beans after
|
|
an explicit stop, but it may also be used to start components that
|
|
have not been configured for autostart , for example, components
|
|
that have not already started on initialization.</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><classname>ContextStoppedEvent</classname></entry>
|
|
|
|
<entry>Published when the
|
|
<interfacename>ApplicationContext</interfacename> is stopped,
|
|
using the <methodname>stop()</methodname> method on the
|
|
<interfacename>ConfigurableApplicationContext</interfacename>
|
|
interface. "Stopped" here means that all
|
|
<interfacename>Lifecycle</interfacename> beans receive an explicit
|
|
stop signal. A stopped context may be restarted through a
|
|
<methodname>start()</methodname> call.</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><classname>ContextClosedEvent</classname></entry>
|
|
|
|
<entry>Published when the
|
|
<interfacename>ApplicationContext</interfacename> is closed, using
|
|
the <methodname>close()</methodname> method on the
|
|
<interfacename>ConfigurableApplicationContext</interfacename>
|
|
interface. "Closed" here means that all singleton beans are
|
|
destroyed. A closed context reaches its end of life; it cannot be
|
|
refreshed or restarted.</entry>
|
|
</row>
|
|
|
|
<row>
|
|
<entry><classname>RequestHandledEvent</classname></entry>
|
|
|
|
<entry>A web-specific event telling all beans that an HTTP request
|
|
has been serviced. This event is published
|
|
<emphasis>after</emphasis> the request is complete. This event is
|
|
only applicable to web applications using Spring's
|
|
<classname>DispatcherServlet</classname>.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
|
|
<para>You can also create and publish your own custom events. This example
|
|
demonstrates a simple class that extends Spring's
|
|
<classname>ApplicationEvent</classname> base class:</para>
|
|
|
|
<programlisting language="java">public class BlackListEvent extends ApplicationEvent {
|
|
private final String address;
|
|
private final String test;
|
|
|
|
public BlackListEvent(Object source, String address, String test) {
|
|
super(source);
|
|
this.address = address;
|
|
this.test = test;
|
|
}
|
|
|
|
<lineannotation>// accessor and other methods...</lineannotation>
|
|
}</programlisting>
|
|
|
|
<para>To publish a custom <classname>ApplicationEvent</classname>, call the
|
|
<methodname>publishEvent()</methodname> method on an
|
|
<interfacename>ApplicationEventPublisher</interfacename>. Typically this
|
|
is done by creating a class that implements
|
|
<interfacename>ApplicationEventPublisherAware</interfacename> and
|
|
registering it as a Spring bean. The following example demonstrates such a
|
|
class:</para>
|
|
|
|
<programlisting language="java"><![CDATA[public class EmailService implements ApplicationEventPublisherAware {
|
|
|
|
private List<String> blackList;
|
|
private ApplicationEventPublisher publisher;
|
|
|
|
public void setBlackList(List<String> blackList) {
|
|
this.blackList = blackList;
|
|
}
|
|
|
|
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
|
|
this.publisher = publisher;
|
|
}
|
|
|
|
public void sendEmail(String address, String text) {
|
|
if (blackList.contains(address)) {
|
|
BlackListEvent event = new BlackListEvent(this, address, text);
|
|
publisher.publishEvent(event);
|
|
return;
|
|
}
|
|
]]><lineannotation>// send email...</lineannotation><![CDATA[
|
|
}
|
|
}]]></programlisting>
|
|
|
|
<para>At configuration time, the Spring container will detect that
|
|
<classname>EmailService</classname> implements
|
|
<interfacename>ApplicationEventPublisherAware</interfacename> and will
|
|
automatically call
|
|
<methodname>setApplicationEventPublisher()</methodname>. In reality, the
|
|
parameter passed in will be the Spring container itself; you're simply
|
|
interacting with the application context via its
|
|
<interfacename>ApplicationEventPublisher</interfacename> interface.</para>
|
|
|
|
<para>To receive the custom <classname>ApplicationEvent</classname>, create
|
|
a class that implements <interfacename>ApplicationListener</interfacename>
|
|
and register it as a Spring bean. The following example demonstrates such
|
|
a class:</para>
|
|
|
|
<programlisting language="java"><![CDATA[public class BlackListNotifier implements ApplicationListener<BlackListEvent> {
|
|
|
|
private String notificationAddress;
|
|
|
|
public void setNotificationAddress(String notificationAddress) {
|
|
this.notificationAddress = notificationAddress;
|
|
}
|
|
|
|
public void onApplicationEvent(BlackListEvent event) {
|
|
]]><lineannotation> // notify appropriate parties via notificationAddress...</lineannotation><![CDATA[
|
|
}
|
|
}]]></programlisting>
|
|
|
|
<para>Notice that <interfacename>ApplicationListener</interfacename> is
|
|
generically parameterized with the type of your custom event,
|
|
<classname>BlackListEvent</classname>. This means that the
|
|
<methodname>onApplicationEvent()</methodname> method can remain type-safe,
|
|
avoiding any need for downcasting. You may register as many event
|
|
listeners as you wish, but note that by default event listeners receive
|
|
events synchronously. This means the
|
|
<methodname>publishEvent()</methodname> method blocks until all listeners
|
|
have finished processing the event. One advantage of this synchronous and
|
|
single-threaded approach is that when a listener receives an event, it
|
|
operates inside the transaction context of the publisher if a transaction
|
|
context is available. If another strategy for event publication becomes
|
|
necessary, refer to the JavaDoc for Spring's
|
|
<interfacename>ApplicationEventMulticaster</interfacename>
|
|
interface.</para>
|
|
|
|
<para>The following example demonstrates the bean definitions used to
|
|
register and configure each of the classes above:</para>
|
|
<programlisting language="xml"><![CDATA[<bean id="emailService" class="example.EmailService">
|
|
<property name="blackList">
|
|
<list>
|
|
<value>black@list.org</value>
|
|
<value>white@list.org</value>
|
|
<value>john@doe.org</value>
|
|
</list>
|
|
</property>
|
|
</bean>
|
|
|
|
<bean id="blackListNotifier" class="example.BlackListNotifier">
|
|
<property name="notificationAddress" value="spam@list.org"/>
|
|
</bean>]]></programlisting>
|
|
|
|
<para>Putting it all together, when the <methodname>sendEmail()</methodname>
|
|
method of the <literal>emailService</literal> bean is called, if there are
|
|
any emails that should be blacklisted, a custom event of type
|
|
<classname>BlackListEvent</classname> is published. The
|
|
<literal>blackListNotifier</literal> bean is registered as an
|
|
<interfacename>ApplicationListener</interfacename> and thus receives the
|
|
<classname>BlackListEvent</classname>, at which point it can notify
|
|
appropriate parties.</para>
|
|
|
|
<note>
|
|
<para>Spring's eventing mechanism is designed for simple communication
|
|
between Spring beans within the same application context. However, for
|
|
more sophisticated enterprise integration needs, the
|
|
separately-maintained <ulink
|
|
url="http://springsource.org/spring-integration">Spring
|
|
Integration</ulink> project provides complete support for building
|
|
lightweight, <ulink url="http://www.enterpriseintegrationpatterns.com"
|
|
>pattern-oriented</ulink>, event-driven architectures that build upon
|
|
the well-known Spring programming model.</para>
|
|
</note>
|
|
</section>
|
|
|
|
<section id="context-functionality-resources">
|
|
<title>Convenient access to low-level resources</title>
|
|
|
|
<para>For optimal usage and understanding of application contexts, users
|
|
should generally familiarize themselves with Spring's
|
|
<interfacename>Resource</interfacename> abstraction, as described in the
|
|
chapter <xref linkend="resources"/>.</para>
|
|
|
|
<para>An application context is a
|
|
<interfacename>ResourceLoader</interfacename>, which can be used to load
|
|
<interfacename>Resource</interfacename>s. A
|
|
<interfacename>Resource</interfacename> is essentially a more feature rich
|
|
version of the JDK class <literal>java.net.URL</literal>, in fact, the
|
|
implementations of the <interfacename>Resource</interfacename> wrap an
|
|
instance of <literal>java.net.URL</literal> where appropriate. A
|
|
<interfacename>Resource</interfacename> can obtain low-level resources
|
|
from almost any location in a transparent fashion, including from the
|
|
classpath, a filesystem location, anywhere describable with a standard
|
|
URL, and some other variations. If the resource location string is a
|
|
simple path without any special prefixes, where those resources come from
|
|
is specific and appropriate to the actual application context type.</para>
|
|
|
|
<para>You can configure a bean deployed into the application context to
|
|
implement the special callback interface,
|
|
<interfacename>ResourceLoaderAware</interfacename>, to be automatically
|
|
called back at initialization time with the application context itself
|
|
passed in as the <interfacename>ResourceLoader</interfacename>. You can
|
|
also expose properties of type <interfacename>Resource</interfacename>, to
|
|
be used to access static resources; they will be injected into it like any
|
|
other properties. You can specify those
|
|
<interfacename>Resource</interfacename> properties as simple String paths,
|
|
and rely on a special JavaBean
|
|
<interfacename>PropertyEditor</interfacename> that is automatically
|
|
registered by the context, to convert those text strings to actual
|
|
<interfacename>Resource</interfacename> objects when the bean is
|
|
deployed.</para>
|
|
|
|
<para>The location path or paths supplied to an
|
|
<interfacename>ApplicationContext</interfacename> constructor are actually
|
|
resource strings, and in simple form are treated appropriately to the
|
|
specific context implementation.
|
|
<classname>ClassPathXmlApplicationContext</classname> treats a simple
|
|
location path as a classpath location. You can also use location paths
|
|
(resource strings) with special prefixes to force loading of definitions
|
|
from the classpath or a URL, regardless of the actual context type.</para>
|
|
</section>
|
|
|
|
<section id="context-create">
|
|
<title>Convenient <interfacename>ApplicationContext</interfacename>
|
|
instantiation for web applications</title>
|
|
|
|
<para>You can create <interfacename>ApplicationContext</interfacename>
|
|
instances declaratively by using, for example, a
|
|
<classname>ContextLoader</classname>. Of course you can also create
|
|
<interfacename>ApplicationContext</interfacename> instances
|
|
programmatically by using one of the
|
|
<interfacename>ApplicationContext</interfacename> implementations.</para>
|
|
|
|
<para>The <classname>ContextLoader</classname> mechanism comes in two
|
|
flavors: the <classname>ContextLoaderListener</classname> and the
|
|
<classname>ContextLoaderServlet</classname>. They have the same
|
|
functionality but differ in that the listener version is not reliable in
|
|
Servlet 2.3 containers. In the Servlet 2.4 specification, Servlet context
|
|
listeners must execute immediately after the Servlet context for the web
|
|
application is created and is available to service the first request (and
|
|
also when the Servlet context is about to be shut down). As such a Servlet
|
|
context listener is an ideal place to initialize the Spring
|
|
<interfacename>ApplicationContext</interfacename>. All things being equal,
|
|
you should probably prefer <classname>ContextLoaderListener</classname>;
|
|
for more information on compatibility, have a look at the Javadoc for the
|
|
<classname>ContextLoaderServlet</classname>.</para>
|
|
|
|
<para>You can register an <interfacename>ApplicationContext</interfacename>
|
|
using the <classname>ContextLoaderListener</classname> as follows:</para>
|
|
|
|
<programlisting language="xml"><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>
|
|
|
|
<lineannotation><!-- or use the <classname>ContextLoaderServlet</classname> instead of the above listener</lineannotation><emphasis>
|
|
<servlet>
|
|
<servlet-name>context</servlet-name>
|
|
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
|
|
<load-on-startup>1</load-on-startup>
|
|
</servlet>
|
|
--</emphasis>></programlisting>
|
|
|
|
<para>The listener inspects the <literal>contextConfigLocation</literal>
|
|
parameter. If the parameter does not exist, the listener uses
|
|
<literal>/WEB-INF/applicationContext.xml</literal> as a default. When the
|
|
parameter <emphasis>does</emphasis> exist, the listener separates the
|
|
String by using predefined delimiters (comma, semicolon and whitespace)
|
|
and uses the values as locations where application contexts will be
|
|
searched. Ant-style path patterns are supported as well. Examples are
|
|
<literal>/WEB-INF/*Context.xml</literal> for all files with names ending
|
|
with "Context.xml", residing in the "WEB-INF" directory, and
|
|
<literal>/WEB-INF/**/*Context.xml</literal>, for all such files in any
|
|
subdirectory of "WEB-INF".</para>
|
|
|
|
<para>You can use <classname>ContextLoaderServlet</classname> instead of
|
|
<classname>ContextLoaderListener</classname>. The Servlet uses the
|
|
<literal>contextConfigLocation</literal> parameter just as the listener
|
|
does.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Deploying a Spring ApplicationContext as a J2EE RAR file</title>
|
|
|
|
<para>In Spring 2.5 and later, it is possible to deploy a Spring
|
|
ApplicationContext as a RAR file, encapsulating the context and all of its
|
|
required bean classes and library JARs in a J2EE RAR deployment unit. This
|
|
is the equivalent of bootstrapping a standalone ApplicationContext, just
|
|
hosted in J2EE environment, being able to access the J2EE servers
|
|
facilities. RAR deployment is a more natural alternative to scenario of
|
|
deploying a headless WAR file, in effect, a WAR file without any HTTP
|
|
entry points that is used only for bootstrapping a Spring
|
|
ApplicationContext in a J2EE environment.</para>
|
|
|
|
<para>RAR deployment is ideal for application contexts that do not need HTTP
|
|
entry points but rather consist only of message endpoints and scheduled
|
|
jobs. Beans in such a context can use application server resources such as
|
|
the JTA transaction manager and JNDI-bound JDBC DataSources and JMS
|
|
ConnectionFactory instances, and may also register with the platform's JMX
|
|
server - all through Spring's standard transaction management and JNDI and
|
|
JMX support facilities. Application components can also interact with the
|
|
application server's JCA WorkManager through Spring's
|
|
<interfacename>TaskExecutor</interfacename> abstraction.</para>
|
|
|
|
<para>Check out the JavaDoc of the <ulink
|
|
url="http://static.springframework.org/spring/docs/3.0.x/javadoc-api/org/springframework/jca/context/SpringContextResourceAdapter.html"
|
|
>SpringContextResourceAdapter</ulink> class for the configuration details
|
|
involved in RAR deployment.</para>
|
|
|
|
<para><emphasis>For a simple deployment of a Spring ApplicationContext as a
|
|
J2EE RAR file:</emphasis> package all application classes into a RAR file,
|
|
which is a standard JAR file with a different file extension. Add all
|
|
required library JARs into the root of the RAR archive. Add a
|
|
"META-INF/ra.xml" deployment descriptor (as shown in
|
|
<classname>SpringContextResourceAdapter</classname>s JavaDoc) and the
|
|
corresponding Spring XML bean definition file(s) (typically
|
|
"META-INF/applicationContext.xml"), and drop the resulting RAR file into
|
|
your application server's deployment directory.</para>
|
|
|
|
<note>
|
|
<para>Such RAR deployment units are usually self-contained; they do not
|
|
expose components to the outside world, not even to other modules of the
|
|
same application. Interaction with a RAR-based ApplicationContext
|
|
usually occurs through JMS destinations that it shares with other
|
|
modules. A RAR-based ApplicationContext may also, for example, schedule
|
|
some jobs, reacting to new files in the file system (or the like). If it
|
|
needs to allow synchronous access from the outside, it could for example
|
|
export RMI endpoints, which of course may be used by other application
|
|
modules on the same machine.</para>
|
|
</note>
|
|
</section>
|
|
</section>
|