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的父类,下面附上它们的继承关系在这里插入图片描述

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

未完待续…

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/20576.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论