Spring iOC主流程初始化方法org.springframework.context.support.AbstractApplicationContext#refresh方法

Spring iOC主流程初始化方法org.springframework.context.support.AbstractApplicationContext#refresh方法

##### 啓動測試類

  @Test
    public void  beanTest(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        Result bean = context.getBean(Result.class);

        context.close();
    }
}

1.ClassPathXmlApplicationContext 構造方法

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
		this(new String[] {configLocation}, true, null);
	}


在這裏插入圖片描述
調用了另一個構造方法

2. ClassPathXmlApplicationContext
	public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {
		/**
		 * 初始化父類
		 */
		super(parent);
		/**
		 * 設置本地資源配置
		 */
		setConfigLocations(configLocations);
		/**
		 * 完成Spring Bean的初始化
		 */
		if (refresh) {
			/**
			 * 構造方法
			 */
			refresh();
		}
	}

在這裏插入圖片描述
父上下文是空

設置配置文件setLocation

public void setConfigLocations(@Nullable String... locations) {
		/**
		 * 配置文件可以有多個循環處理
		 */
		if (locations != null) {
			Assert.noNullElements(locations, "Config locations must not be null");
			this.configLocations = new String[locations.length];
			for (int i = 0; i < locations.length; i++) {
				/**
				 * 把傳進來的配置文件賦值給一個數組
				 */
				this.configLocations[i] = resolvePath(locations[i]).trim();
			}
		}
		else {
			this.configLocations = null;
		}
	}

refresh()核心方法


	public void refresh() throws BeansException, IllegalStateException {
		/**
		 * 加鎖,說明併發執行,很多地方都有調用
		 * registerShutdownHook 也調用了
		 * close()方法也調有了,
		 * 容器在啓動時,不能調Close的方法
		 */
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			/**
			 * 預初始化
			 */
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			/**
			 *
			 * 創建BeanFactory工廠,告訴子類去刷新內部BeanFactory,
			 * 加載Bean信息,並封裝爲BeanDefinition,並註冊到BeanDefinitionRegistry
			 * key-value key :bean的id value就是BeanDefinition
			 */
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			/**
			 * 準備BeanFactory,進行一些設置
			 * Context的類加載器
			 */
			prepareBeanFactory(beanFactory);

			try {
				/**
				 * BeanFactory準備完成後,後置處理器增強,空方法
				 */
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);


				// Invoke factory processors registered as beans in the context.
				/**
				 * 實例化實現了BeanFactoryPostProcessor接口的類中構造方法
				 * 並調用用postProcessBeanFactory 方法
				 *
				 */
				invokeBeanFactoryPostProcessors(beanFactory);


				// Register bean processors that intercept bean creation.
				/**
				 *將實現了BeanPostProcessor的構造方法
				 */
				registerBeanPostProcessors(beanFactory);

				/**
				 * 初始化國際華資源MessageSource組牛
				 */
				// Initialize message source for this context.
				initMessageSource();

				/**
				 * 初始化事件派發器
				 */
				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				/**
				 * 空方法
				 * 如果子類重寫了這個方法就,調用子類重寫的方法tomcat jetty之類的
				 */
				// Initialize other special beans in specific context subclasses.
				onRefresh();

				/**
				 * 註冊應用監聽器就是實現了ApplicationContextListener接口Bean
				 */
				// Check for listener beans and register them.
				registerListeners();
					/**
					 * 執行構造方法1
					 * setter方法2
					 * 實現了BeanNameAware接口的setBeanName方法3
					 * 實現了BeanFactoryAware接口的 setBeanFactory(BeanFactory beanFactory)方法4
					 * 實現了ApplicationContextAware接口的setsetApplicationContext 方法5
					 * 實現了BeanPostProcessor接口的postProcessBeforeInitialization方法6 ,AOP原理
					 * 標有PostConstruct註解的方法 7
					 * 實現了InitializingBean接口的afterPropertiesSet方法8
					 * 調用配置了init-method方法 9
					 * 實現了BeanPostProcessor接口的postProcessAfterInitialization方法 10
					 *
					 */
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				/**
				 * 完成刷新Context,主要調用org.springframework.context.LifecycleProcessor接口onRefresh方法,發佈事件ContextRefreshedEvent事件
				 */
				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}
				/**
				 * 銷燬Bean
				 */
				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				/**
				 * 重置Active標誌爲false
				 * this.active.set(false);
				 */
				// 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();
			}
		}
	}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章