Spring——Spring IOC容器初始化过程

Spring IOC容器的初始化简单的可以分为三个过程:

  1. 第一个过程是Resource资源定位。这个Resouce指的是BeanDefinition的资源定位。这个过程就是容器找数据的过程,就像水桶装水需要先找到水一样。(将xml, db.properties等文件打包成一个BeanDefinition)
  2. 第二个过程是BeanDefinition的载入过程。这个载入过程是把用户定义好的Bean表示成Ioc容器内部的数据结构,而这个容器内部的数据结构就是BeanDefition。(将BeanDefinition载入,这是Bean就产生了,只不过还没实例化)
  3. ​ 第三个过程是向IOC容器注册这些BeanDefinition的过程,这个过程就是将前面的BeanDefition保存到HashMap中的过程。(实例化出这些Bean,由反射完成)

所以实际上IOC注入的那个容器,实际上就是HashMap

Spring 初始化流程

我们从这一步打断点进入,一步步剖析Spring启动的过程

ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");

接下来会进入AbstractApplicationContext类的静态初始块,AbstractApplicationContext是ClassPathXmlApplicationContext的父类,下面附上它们的继承关系Spring——Spring IOC容器初始化过程_第1张图片

static {
     
		// Eagerly load the ContextClosedEvent class to avoid weird classloader issues
		// on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
		ContextClosedEvent.class.getName();
}

这句话没有什么特别的实际作用,我们接下去

	/**
	 * Create a new ClassPathXmlApplicationContext, loading the definitions
	 * from the given XML file and automatically refreshing the context.
	 * @param configLocation resource location
	 * @throws BeansException if context creation failed
	 */
	public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
     
		this(new String[] {
     configLocation}, true, null);
	}

其中的this构造方法,是下面这一个

	/**
	 * Create a new ClassPathXmlApplicationContext with the given parent,
	 * loading the definitions from the given XML files.
	 * @param configLocations array of resource locations
	 * @param refresh whether to automatically refresh the context,
	 * loading all bean definitions and creating all singletons.
	 * Alternatively, call refresh manually after further configuring the context.
	 * @param parent the parent context
	 * @throws BeansException if context creation failed
	 * @see #refresh()
	 */
	public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {
     

		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
     
			refresh();
		}
	}

里面的super(parent)会调用一系列父类的的构造方法,最终到达AbstractApplicationContext的构造方法,这实际上是一堆父类容器的初始过程。接下来的setConfigLocations则是解析xml文件**(资源定位过程)**,将所有的配置项读取到Spring中保存(这时候一个BeanDefinition就创建好了

最重要的Spring初始化过程其实都在refresh方法里

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

未完待续…

你可能感兴趣的:(spring,ioc,java)