Spring IoC 详解

一.  Spring Core 官方文档

Chapter 1. The IoC container
1.1. Introduction to the Spring IoC container and
beans
This chapter covers the Spring Framework implementation of the Inversion of Control (IoC) [1: See
Inversion of Control] 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 the
WebApplicationContext for use in web applications.
In short, the BeanFactory provides the configuration framework and basic functionality, and the
ApplicationContext adds more enterprise-specific functionality. The ApplicationContext 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 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 the dependencies among them, are reflected in the configuration
metadata used by a container.
1.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 of
ClassPathXmlApplicationContext or FileSystemXmlApplicationContext. While XML has been the
traditional format for defining configuration metadata you can instruct the container to use Java
2
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 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 1. The Spring IoC container 

二.IoC概念

IoC : Inversion of Control 控制反转.

Spring 中 将Java Bean 的生命周期交给 Spring 的 Ioc 容器管理, 当程序中需要使用Bean时,直接从窗口中获取.

三.IoC 容器

org.springframework.context.ApplicationContext 接口是IoC容器的父接口.

它的主要实现类有三个:

ClassPathXmlApplicationContext :  从项目的根目录下读取配置文件的实现形式

FileSystemXmlApplicationContext:  从系统文件读取配置文件的实现形式

AnnotationConfigApplicationContext: 通过注解的实现形式

四. 容器的初始化和Bean的载入

1.ClassPathXmlApplicationContext  和  FileSystemXmlApplicationContext 

都会调用 ContextLoaderListener 类中的初始化容器;

调用abstractApplicationContext.refresh 方法载入Bean对象至容器中

	public FileSystemXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {

		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
			refresh();
		}
	}
	public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {

		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
			refresh();
		}
	}
	/**
	 * Initialize the root web application context.
	 */
	@Override
	public void contextInitialized(ServletContextEvent event) {
		initWebApplicationContext(event.getServletContext());
	}

  

/**
 * Load or refresh the persistent representation of the configuration,
 * which might an XML file, properties file, or relational database schema.
 * <p>As this is a startup method, it should destroy already created singletons
 * if it fails, to avoid dangling resources. In other words, after invocation
 * of that method, either all or no singletons at all should be instantiated.
 * @throws BeansException if the bean factory could not be initialized
 * @throws IllegalStateException if already initialized and multiple refresh
 * attempts are not supported
 */
void refresh() throws BeansException, IllegalStateException;






     

  

    @Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

  

原文地址:https://www.cnblogs.com/kplsm123/p/12046899.html