[TOC]
### 1.2. Container Overview
The`org.springframework.context.ApplicationContext`interface represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the 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 lets you express the objects that compose your application and the rich interdependencies between those objects.
Several implementations of the`ApplicationContext`interface are supplied with Spring. In stand-alone applications, it is common to create an instance of[`ClassPathXmlApplicationContext`](https://docs.spring.io/spring-framework/docs/5.2.8.RELEASE/javadoc-api/org/springframework/context/support/ClassPathXmlApplicationContext.html)or[`FileSystemXmlApplicationContext`](https://docs.spring.io/spring-framework/docs/5.2.8.RELEASE/javadoc-api/org/springframework/context/support/FileSystemXmlApplicationContext.html). 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 typically suffices (see[Convenient ApplicationContext Instantiation for Web Applications](https://docs.spring.io/spring/docs/5.2.8.RELEASE/spring-framework-reference/core.html#context-create)). If you use the[Spring Tools for Eclipse](https://spring.io/tools)(an Eclipse-powered development environment), you can easily create this boilerplate configuration with a few mouse clicks or keystrokes.
The following diagram shows 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.
![container magic](https://docs.spring.io/spring/docs/5.2.8.RELEASE/spring-framework-reference/images/container-magic.png)
Figure 1. The Spring IoC container
#### [](https://docs.spring.io/spring/docs/5.2.8.RELEASE/spring-framework-reference/core.html#beans-factory-metadata)1.2.1. 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](https://docs.spring.io/spring/docs/5.2.8.RELEASE/spring-framework-reference/core.html#beans-annotation-config): Spring 2.5 introduced support for annotation-based configuration metadata.
* [Java-based configuration](https://docs.spring.io/spring/docs/5.2.8.RELEASE/spring-framework-reference/core.html#beans-java): 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`](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html),[`@Bean`](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Bean.html),[`@Import`](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Import.html), and[`@DependsOn`](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/DependsOn.html)annotations.
Spring configuration consists of at least one and typically more than one ***bean definition*** that the container must manage. XML-based configuration metadata configures these beans 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](https://docs.spring.io/spring/docs/5.2.8.RELEASE/spring-framework-reference/core.html#aop-atconfigurable).
The following example shows the basic structure of XML-based configuration metadata:
~~~xml
<?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
https://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 identifies 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](https://docs.spring.io/spring/docs/5.2.8.RELEASE/spring-framework-reference/core.html#beans-dependencies)for more information.
#### 1.2.2. Instantiating a Container
The location path or paths supplied to an`ApplicationContext`constructor are resource strings that let the container load configuration metadata from a variety of external resources, such as the local file system, the Java`CLASSPATH`, and so on.
> Java
~~~java
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
~~~
After you learn about Spring’s IoC container, you may want to know more about Spring’s Resourceabstraction (as described in 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 Application Contexts and Resource Paths.
The following example shows the service layer objects`(services.xml)`configuration file:
~~~xml
<?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
https://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>
</beans>
~~~
The following example shows the data access objects`daos.xml`file:
~~~xml
<?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
https://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`PetStoreServiceImpl`class and two data access objects of the types`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](https://docs.spring.io/spring/docs/5.2.8.RELEASE/spring-framework-reference/core.html#beans-dependencies).
##### Composing XML-based Configuration Metadata
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](https://docs.spring.io/spring/docs/5.2.8.RELEASE/spring-framework-reference/core.html#beans-factory-instantiation). Alternatively, use one or more occurrences of the`<import/>`element to load bean definitions from another file or files. The following example shows how to do so:
~~~xml
<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. However, 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.
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 namespace itself provides the import directive feature. Further configuration features beyond plain bean definitions are available in a selection of XML namespaces provided by Spring — for example, the`context`and`util`namespaces.
##### [](https://docs.spring.io/spring/docs/5.2.8.RELEASE/spring-framework-reference/core.html#groovy-bean-definition-dsl)The Groovy Bean Definition DSL
As a further example for externalized configuration metadata, bean definitions can also be expressed in Spring’s Groovy Bean Definition DSL, as known from the Grails framework. Typically, such configuration live in a ".groovy" file with the structure shown in the following example:
~~~groovy
beans {
dataSource(BasicDataSource) {
driverClassName = "org.hsqldb.jdbcDriver"
url = "jdbc:hsqldb:mem:grailsDB"
username = "sa"
password = ""
settings = [mynew:"setting"]
}
sessionFactory(SessionFactory) {
dataSource = dataSource
}
myService(MyService) {
nestedBean = { AnotherBean bean ->
dataSource = dataSource
}
}
}
~~~
This configuration style is largely equivalent to XML bean definitions and even supports Spring’s XML configuration namespaces. It also allows for importing XML bean definition files through an`importBeans`directive.
#### [](https://docs.spring.io/spring/docs/5.2.8.RELEASE/spring-framework-reference/core.html#beans-factory-client)1.2.3. Using the Container
The`ApplicationContext`is the interface for an advanced factory capable of maintaining a registry of different beans and their dependencies. By using the method`T getBean(String name, Class<T> requiredType)`, you can retrieve instances of your beans.
The`ApplicationContext`lets you read bean definitions and access them, as the following example shows:
```
// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);
// use configured instance
List userList = service.getUsernameList();
```
The most flexible variant is` **GenericApplicationContext** `in combination with reader delegates — for example, with`XmlBeanDefinitionReader`for XML files, as the following example shows:
```
GenericApplicationContext context = new GenericApplicationContext();
new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml");
context.refresh();
```
**You can also use the`GroovyBeanDefinitionReader`for Groovy files, as the following example shows:**
Java
~~~
GenericApplicationContext context = new GenericApplicationContext();
new GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy");
context.refresh();
~~~
You can mix and match such reader delegates on the same`ApplicationContext`, reading bean definitions from diverse configuration sources.
You can then 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 have no dependency on Spring APIs at all. For example, Spring’s integration with web frameworks **provides dependency injection for various web framework components such as controllers** and JSF-managed beans, letting you declare a dependency on a specific bean through metadata (such as an autowiring annotation).