Introduction to the Spring IoC container and beans
This chapter covers the Spring Framework implementation of the Inversion of Control (IoC) [1] principle. IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes, or a mechanism such as the Service Locator pattern.
The
org.springframework.beans
and org.springframework.context
packages are the basis for Spring Framework’s IoC container. The BeanFactory
interface provides an advanced configuration mechanism capable of managing any type of object. ApplicationContext
is a sub-interface of BeanFactory
. It adds easier integration with Spring’s AOP features; message resource handling (for use in internationalization), event publication; and application-layer specific contexts such as theWebApplicationContext
for use in web applications.
In short, the
BeanFactory
provides the configuration framework and basic functionality, and the ApplicationContext
adds more enterprise-specific functionality. TheApplicationContext
is a complete superset of the BeanFactory
, and is used exclusively in this chapter in descriptions of Spring’s IoC container. For more information on using the BeanFactory
instead of the ApplicationContext,
refer to Section 6.16, “The BeanFactory”.
In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. Beans, and thedependencies among them, are reflected in the configuration metadata used by a container.
6.2 Container overview
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 ofClassPathXmlApplicationContext
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 providing 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 web descriptor XML in the
web.xml
file of the application will typically suffice (see Section 6.15.4, “Convenient ApplicationContext instantiation for web applications”). If you are using the Spring Tool Suite Eclipse-powered development environment 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.
Figure 6.1. The Spring IoC container
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.
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>
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".Configuration metadata
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.
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. These days many developers choose Java-based configuration for their Spring applications.
|
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. Java configuration typically uses @Bean
annotated methods within a @Configuration
class.
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.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.6.2.2 Instantiating a container
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"});
After you learn about Spring’s IoC container, you may want to know more about Spring’s
Resource abstraction, as described in Chapter 7, Resources, which provides a convenient mechanism for reading an InputStream from locations defined in a URI syntax. In particular, Resource paths are used to construct applications contexts as described in Section 7.7, “Application contexts and Resource paths”. |
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.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.xsd"> <bean id="accountDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao"> <!-- additional collaborators and configuration for this bean go here --> </bean> <bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao"> <!-- 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 JpaAccountDao
and JpaItemDao
(based on the JPA Object/Relational mapping standard). 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.
No comments:
Post a Comment