The interface
org.springframework.context.ApplicationContext
represents the Spring IoC container and is responsible for instantiating,
configuring, and assembling the aforementioned beans. The container gets
its instructions on what objects to instantiate, configure, and assemble
by reading configuration metadata. The configuration metadata is
represented in XML, Java annotations, or Java code. It allows you to
express the objects that compose your application and the rich
interdependencies between such objects.
Several implementations of the
ApplicationContext
interface are supplied
out-of-the-box with Spring. In standalone applications it is common to
create an instance of ClassPathXmlApplicationContext
or FileSystemXmlApplicationContext
.
While XML has been the traditional format
for defining configuration metadata you can instruct the container to use
Java annotations or code as the metadata format by providng a small amount
of XML configuration to declaratively enable support for these additional
metadata formats.
In most application scenarios, explicit user code is not required to
instantiate one or more instances of a Spring IoC container. For example,
in a web application scenario, a simple eight (or so) lines of boilerplate
J2EE web descriptor XML in the web.xml
file of the
application will typically suffice (see Section 3.13.4, “Convenient ApplicationContext
instantiation for web applications”). If you are using the SpringSource Tool
Suite Eclipse-powered development environment or Spring Roo this boilerplate
configuration can be easily created with few mouse clicks or
keystrokes.
The following diagram is a high-level view of how Spring works. Your
application classes are combined with configuration metadata so that after
the ApplicationContext
is created and initialized,
you have a fully configured and executable system or application.
As the preceding diagram shows, the Spring IoC container consumes a form of configuration metadata; this configuration metadata represents how you as an application developer tell the Spring container to instantiate, configure, and assemble the objects in your application.
Configuration metadata is traditionally supplied in a simple and intuitive XML format, which is what most of this chapter uses to convey key concepts and features of the Spring IoC container.
Note | |
---|---|
XML-based metadata is not the only allowed form of configuration metadata. The Spring IoC container itself is totally decoupled from the format in which this configuration metadata is actually written. |
For information about using other forms of metadata with the Spring container, see:
Annotation-based configuration: Spring 2.5 introduced support for annotation-based configuration metadata.
Java-based
configuration: Starting with Spring 3.0, many features
provided by the Spring JavaConfig
project became part of the core Spring Framework. Thus you
can define beans external to your application classes by using Java
rather than XML files. To use these new features, see the
@Configuration
, @Bean,
@Import
and
@DependsOn
annotations.
Spring configuration consists of at least one and typically more
than one bean definition that the container must manage. XML-based
configuration metadata shows these beans configured as
<bean/>
elements inside a top-level
<beans/>
element.
These bean definitions correspond to the actual objects that make
up your application. Typically you define service layer objects, data
access objects (DAOs), presentation objects such as Struts
Action
instances, infrastructure objects
such as Hibernate SessionFactories
, JMS
Queues
, and so forth. Typically one does
not configure fine-grained domain objects in the container, because it
is usually the responsibility of DAOs and business logic to create and
load domain objects. However, you can use Spring's integration with
AspectJ to configure objects that have been created outside the control
of an IoC container. See Using
AspectJ to dependency-inject domain objects with Spring.
The following example shows the basic structure of XML-based configuration metadata:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean> <bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean> <!-- more bean definitions go here --> </beans>
The id
attribute is a string that you use to
identify the individual bean definition. The class
attribute defines the type of the bean and uses the fully qualified
classname. The value of the id attribute refers to collaborating
objects. The XML for referring to collaborating objects is not shown in
this example; see Dependencies
for more information.
Instantiating a Spring IoC container is straightforward. The
location path or paths supplied to an
ApplicationContext
constructor are
actually resource strings that allow the container to load configuration
metadata from a variety of external resources such as the local file
system, from the Java CLASSPATH
, and so on.
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});
Note | |
---|---|
After you learn about Spring's IoC container, you may want to
know more about Spring's |
The following example shows the service layer objects
(services.xml)
configuration file:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- services --> <bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl"> <property name="accountDao" ref="accountDao"/> <property name="itemDao" ref="itemDao"/> <!-- additional collaborators and configuration for this bean go here --> </bean> <!-- more bean definitions for services go here --> </beans>
The following example shows the data access objects
daos.xml
) file:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="accountDao" class="org.springframework.samples.jpetstore.dao.ibatis.SqlMapAccountDao"> <!-- additional collaborators and configuration for this bean go here --> </bean> <bean id="itemDao" class="org.springframework.samples.jpetstore.dao.ibatis.SqlMapItemDao"> <!-- additional collaborators and configuration for this bean go here --> </bean> <!-- more bean definitions for data access objects go here --> </beans>
In the preceding example, the service layer consists of the class
PetStoreServiceImpl
, and two data access objects
of the type SqlMapAccountDao
and SqlMapItemDao
are based on the iBatis
Object/Relational mapping framework. The property
name
element refers to the name of the JavaBean property, and
the ref
element refers to the name of another bean
definition. This linkage between id and ref elements expresses the
dependency between collaborating objects. For details of configuring an
object's dependencies, see Dependencies.
It can be useful to have bean definitions span multiple XML files. Often each individual XML configuration file represents a logical layer or module in your architecture.
You can use the application context constructor to load bean
definitions from all these XML fragments. This constructor takes
multiple Resource
locations, as was
shown in the previous section. Alternatively, use one or more
occurrences of the <import/>
element to load
bean definitions from another file or files. For example:
<beans> <import resource="services.xml"/> <import resource="resources/messageSource.xml"/> <import resource="/resources/themeSource.xml"/> <bean id="bean1" class="..."/> <bean id="bean2" class="..."/> </beans>
In the preceding example, external bean definitions are loaded
from three files, services.xml
,
messageSource.xml
, and
themeSource.xml
. All location paths are relative to
the definition file doing the importing, so
services.xml
must be in the same directory or
classpath location as the file doing the importing, while
messageSource.xml
and
themeSource.xml
must be in a
resources
location below the location of the
importing file. As you can see, a leading slash is ignored, but given
that these paths are relative, it is better form not to use the slash
at all. The contents of the files being imported, including the top
level <beans/>
element, must be valid XML
bean definitions according to the Spring Schema or DTD.
Note | |
---|---|
It is possible, but not recommended, to reference files in parent directories using a relative "../" path. Doing so creates a dependency on a file that is outside the current application. In particular, this reference is not recommended for "classpath:" URLs (for example, "classpath:../services.xml"), where the runtime resolution process chooses the "nearest" classpath root and then looks into its parent directory. Classpath configuration changes may lead to the choice of a different, incorrect directory. You can always use fully qualified resource locations instead of relative paths: for example, "file:C:/config/services.xml" or "classpath:/config/services.xml". However, be aware that you are coupling your application's configuration to specific absolute locations. It is generally preferable to keep an indirection for such absolute locations, for example, through "${...}" placeholders that are resolved against JVM system properties at runtime. |
The ApplicationContext
is the
interface for an advanced factory capable of maintaining a registry of
different beans and their dependencies. Using the method T
getBean(Stringname, Class<T> requiredType)
you can
retrieve instances of your beans.
The ApplicationContext
enables you
to read bean definitions and access them as follows:
// create and configure beans ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"}); // retrieve configured instance PetStoreServiceImpl service = context.getBean("petStore", PetStoreServiceImpl.class); // use configured instance List userList service.getUsernameList();
You use getBean
to retrieve instances of
your beans. The ApplicationContext
interface has a few other methods for retrieving beans, but ideally your
application code should never use them. Indeed, your application code
should have no calls to the getBean
method at
all, and thus no dependency on Spring APIs at all. For example, Spring's
integration with web frameworks provides for dependency injection for
various web framework classes such as controllers and JSF-managed
beans.