# Additional Capabilities of the ApplicationContext

As was discussed in the chapter introduction, the `org.springframework.beans.factory` package provides basic functionality for managing and manipulating beans, including in a programmatic way. The `org.springframework.context` package adds the ApplicationContext interface, which extends the BeanFactory interface, in addition to extending other interfaces to provide additional functionality in a more application framework-oriented style. Many people use the ApplicationContext in a completely declarative fashion, not even creating it programmatically, but instead relying on support classes such as `ContextLoader` to automatically instantiate an ApplicationContext as part of the normal startup process of a J2EE web application.

To enhance BeanFactory functionality in a more framework-oriented style the context package also provides the following functionality:

- Access to messages in i18n-style, through the MessageSource interface.

- Access to resources, such as URLs and files, through the ResourceLoader interface.

- Event publication to beans implementing the ApplicationListener interface, through the use of the ApplicationEventPublisher interface.

- Loading of multiple (hierarchical) contexts, allowing each to be focused on one particular layer, such as the web layer of an application, through the HierarchicalBeanFactory interface.

## Internationalization using MessageSource

The ApplicationContext interface extends an interface called MessageSource, and therefore provides internationalization (i18n) functionality. Spring also provides the interface `HierarchicalMessageSource`, which can resolve messages hierarchically. Together these interfaces provide the foundation upon which Spring effects message resolution. The methods defined on these interfaces include:

- `String getMessage(String code, Object[] args, String default, Locale loc)`: The basic method used to retrieve a message from the MessageSource. When no message is found for the specified locale, the default message is used. Any arguments passed in become replacement values, using the MessageFormat functionality provided by the standard library.

- `String getMessage(String code, Object[] args, Locale loc)`: Essentially the same as the previous method, but with one difference: no default message can be specified; if the message cannot be found, a `NoSuchMessageException` is thrown.

- `String getMessage(MessageSourceResolvable resolvable, Locale locale)`: All properties used in the preceding methods are also wrapped in a class named MessageSourceResolvable, which you can use with this method.

When an ApplicationContext is loaded, it automatically searches for a MessageSource bean defined in the context. The bean must have the name `messageSource`. 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 ApplicationContext attempts to find a parent containing a bean with the same name. If it does, it uses that bean as the MessageSource. If the ApplicationContext cannot find any source for messages, an empty `DelegatingMessageSource` is instantiated in order to be able to accept calls to the methods defined above.

Spring provides two MessageSource implementations, `ResourceBundleMessageSource` and `StaticMessageSource`. Both implement HierarchicalMessageSource in order to do nested messaging. The `StaticMessageSource` is rarely used but provides programmatic ways to add messages to the source. The `ResourceBundleMessageSource` is shown in the following example:

    <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>

In the example it is assumed you have three resource bundles defined in your classpath called `format`, `exceptions` and `windows`. 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...

    # in format.properties
    message=Alligators rock!

    # in exceptions.properties
    argument.required=The '{0}' argument is required.

A program to execute the `MessageSource` functionality is shown in the next example. Remember that all `ApplicationContext` implementations are also `MessageSource` implementations and so can be cast to the `MessageSource` interface.

    public static void main(String[] args) {
      MessageSource resources = new ClassPathXmlApplicationContext("beans.xml");
      String message = resources.getMessage("message", null, "Default", null);
      System.out.println(message);
    }

The resulting output from the above program will be...

    Alligators rock!

So to summarize, the `MessageSource` is defined in a file called `beans.xml`, which exists at the root of your classpath. The `messageSource` bean definition refers to a number of resource bundles through its `basenames` property. The three files that are passed in the list to the `basenames` property exist as files at the root of your classpath and are called `format.properties`, `exceptions.properties`, and `windows.properties` respectively.

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.

    <beans>

      <!-- this MessageSource is being used in a web application -->
      <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
          <property name="basename" value="exceptions"/>
      </bean>

      <!-- lets inject the above MessageSource into this POJO -->
      <bean id="example" class="com.foo.Example">
          <property name="messages" ref="messageSource"/>
      </bean>

    </beans>

    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);
      }

    }

The resulting output from the invocation of the `execute()` method will be...

    The userDao argument is required.

With regard to internationalization (i18n), Spring's various `MessageResource` implementations follow the same locale resolution and fallback rules as the standard JDK `ResourceBundle`. In short, and continuing with the example `messageSource` defined previously, if you want to resolve messages against the British (en-GB) locale, you would create files called `format_en_GB.properties`, `exceptions_en_GB.properties`, and `windows_en_GB.properties` respectively.

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.

    # in exceptions_en_GB.properties
    argument.required=Ebagum lad, the '{0}' argument is required, I say, required.

    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);
    }

The resulting output from the running of the above program will be...

    Ebagum lad, the 'userDao' argument is required, I say, required.

You can also use the `MessageSourceAware` interface to acquire a reference to any `MessageSource` that has been defined. Any bean that is defined in an `ApplicationContext` that implements the `MessageSourceAware` interface is injected with the application context's `MessageSource` when the bean is created and configured.

As an alternative to `ResourceBundleMessageSource`, Spring provides a `ReloadableResourceBundleMessageSource` class. This variant supports the same bundle file format but is more flexible than the standard JDK based `ResourceBundleMessageSource` implementation. 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 `ReloadableResourceBundleMessageSource` javadoc for details.

## Standard and Custom Events

Event handling in the ApplicationContext is provided through the `ApplicationEvent` class and ApplicationListener interface. If a bean that implements the ApplicationListener interface is deployed into the context, every time an `ApplicationEvent` gets published to the ApplicationContext, that bean is notified. Essentially, this is the standard Observer design pattern. Spring provides the following standard events:

### Built-in Events

Event | Explanation
--- | ---

`ContextRefreshedEvent`

Published when the ApplicationContext is initialized or refreshed, for example, using the `refresh()` method on the ConfigurableApplicationContext interface. "Initialized" here means that all beans are loaded, post-processor beans are detected and activated, singletons are pre-instantiated, and the ApplicationContext 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 ApplicationContext actually supports such "hot" refreshes. For example, `XmlWebApplicationContext` supports hot refreshes, but `GenericApplicationContext` does not.

`ContextStartedEvent`

Published when the ApplicationContext is started, using the `start()` method on the ConfigurableApplicationContext interface. "Started" here means that all Lifecycle 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.

`ContextStoppedEvent` | Published when the ApplicationContext is stopped, using the `stop()` method on the ConfigurableApplicationContext interface. "Stopped" here means that all Lifecycle beans receive an explicit stop signal. A stopped context may be restarted through a `start()` call.
`ContextClosedEvent` | Published when the ApplicationContext is closed, using the `close()` method on the ConfigurableApplicationContext interface. "Closed" here means that all singleton beans are destroyed. A closed context reaches its end of life; it cannot be refreshed or restarted.
`RequestHandledEvent` | A web-specific event telling all beans that an HTTP request has been serviced. This event is published after the request is complete. This event is only applicable to web applications using Spring's `DispatcherServlet`.

You can also create and publish your own custom events. This example demonstrates a simple class that extends Spring's `ApplicationEvent` base class:

    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;
      }

      // accessor and other methods...
    }

To publish a custom `ApplicationEvent`, call the `publishEvent()` method on an ApplicationEventPublisher. Typically this is done by creating a class that implements ApplicationEventPublisherAware and registering it as a Spring bean. The following example demonstrates such a class:

    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;
          }
          // send email...
      }
    }

At configuration time, the Spring container will detect that `EmailService` implements ApplicationEventPublisherAware and will automatically call `setApplicationEventPublisher()`. In reality, the parameter passed in will be the Spring container itself; you're simply interacting with the application context via its ApplicationEventPublisher interface.

To receive the custom `ApplicationEvent`, create a class that implements ApplicationListener and register it as a Spring bean. The following example demonstrates such a class:

    public class BlackListNotifier implements ApplicationListener<BlackListEvent> {

      private String notificationAddress;

      public void setNotificationAddress(String notificationAddress) {
          this.notificationAddress = notificationAddress;
      }

      public void onApplicationEvent(BlackListEvent event) {
            // notify appropriate parties via notificationAddress...
      }
    }

Notice that ApplicationListener is generically parameterized with the type of your custom event, `BlackListEvent`. This means that the `onApplicationEvent()` 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 `publishEvent()` 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 ApplicationEventMulticaster interface.

The following example shows the bean definitions used to register and configure each of the classes above:

    <bean id="emailService" class="example.EmailService">
      <property name="blackList">
          <list>
              <value>known.spammer@example.org</value>
              <value>known.hacker@example.org</value>
              <value>john.doe@example.org</value>
          </list>
      </property>
    </bean>

    <bean id="blackListNotifier" class="example.BlackListNotifier">
      <property name="notificationAddress" value="blacklist@example.org"/>
    </bean>

Putting it all together, when the `sendEmail()` method of the `emailService` bean is called, if there are any emails that should be blacklisted, a custom event of type `BlackListEvent` is published. The `blackListNotifier` bean is registered as an ApplicationListener and thus receives the `BlackListEvent`, at which point it can notify appropriate parties.

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 Spring Integration project provides complete support for building lightweight, pattern-oriented, event-driven architectures that build upon the well-known Spring programming model.

## Convenient access to low-level resources

For optimal usage and understanding of application contexts, users should generally familiarize themselves with Spring's Resource abstraction, as described in the chapter .

An application context is a ResourceLoader, which can be used to load Resources. A Resource is essentially a more feature rich version of the JDK class `java.net.URL`, in fact, the implementations of the Resource wrap an instance of `java.net.URL` where appropriate. A Resource 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.

You can configure a bean deployed into the application context to implement the special callback interface, ResourceLoaderAware, to be automatically called back at initialization time with the application context itself passed in as the ResourceLoader. You can also expose properties of type Resource, to be used to access static resources; they will be injected into it like any other properties. You can specify those Resource properties as simple String paths, and rely on a special JavaBean PropertyEditor that is automatically registered by the context, to convert those text strings to actual Resource objects when the bean is deployed.

The location path or paths supplied to an ApplicationContext constructor are actually resource strings, and in simple form are treated appropriately to the specific context implementation. `ClassPathXmlApplicationContext` 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.

## Convenient ApplicationContext instantiation for web applications

You can create ApplicationContext instances declaratively by using, for example, a `ContextLoader`. Of course you can also create ApplicationContext instances programmatically by using one of the ApplicationContext implementations.

The `ContextLoader` mechanism comes in two flavors: the `ContextLoaderListener` and the `ContextLoaderServlet`. 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 ApplicationContext. All things being equal, you should probably prefer `ContextLoaderListener`; for more information on compatibility, have a look at the Javadoc for the `ContextLoaderServlet`.

You can register an ApplicationContext using the `ContextLoaderListener` as follows:

    <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>

    <!-- or use the ContextLoaderServlet instead of the above listener
    <servlet>
    <servlet-name>context</servlet-name>
    <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>
    -->

The listener inspects the `contextConfigLocation` parameter. If the parameter does not exist, the listener uses `/WEB-INF/applicationContext.xml` as a default. When the parameter does 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 `/WEB-INF/*Context.xml` for all files with names ending with "Context.xml", residing in the "WEB-INF" directory, and `/WEB-INF/**/*Context.xml`, for all such files in any subdirectory of "WEB-INF".

You can use `ContextLoaderServlet` instead of `ContextLoaderListener`. The Servlet uses the `contextConfigLocation` parameter just as the listener does.

## Deploying a Spring ApplicationContext as a J2EE RAR file

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.

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 TaskExecutor abstraction.

Check out the JavaDoc of the SpringContextResourceAdapter class for the configuration details involved in RAR deployment.

For a simple deployment of a Spring ApplicationContext as a J2EE RAR file: 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 `SpringContextResourceAdapter`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.

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.