小さい読むspring iocのソースコード(3)——Xml WebAppleication Contect初期化の全体の過程


前のページでは、Contect LoaderListenerはwebアプリケーションの起動後、一連の前置き手順を経て、Xml WebAppleication Contectの仕事を初期化し、AbstractAplication Contectに委託します.この記事は引き続き紹介します.どのように配置ファイルのロード、解析、登録を完了しましたか?
まずここの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) {
				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

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

				// Propagate exception to caller.
				throw ex;
			}
		}
	}
最初にこの方法は繰り返しのリフレッシュを回避するために同期された.そして更新の各ステップは、個々の方法で明確にし、順番に一つ一つ見ることができます.
まずはprepare Refresh()の方法です.

protected void prepareRefresh() {
		this.startupDate = System.currentTimeMillis();

		synchronized (this.activeMonitor) {
			this.active = true;
		}

		if (logger.isInfoEnabled()) {
			logger.info("Refreshing " + this);
		}

		// Initialize any placeholder property sources in the context environment
		initPropertySources();

		// Validate that all properties marked as required are resolvable
		// see ConfigurablePropertyResolver#setRequiredProperties
		this.environment.validateRequiredProperties();
	}
この方法ですることは多くないです.開始時間を記録して、ログを出力します.また、initPropertySources()方法とvalidateRequired Properties()方法は普通何もしていません.
そして、コアのオーブタインFreeshBenFactory()方法は、BenFactoryを初期化することであり、全体refsh()方法の核心であり、配置ファイルのロード、解析、登録が完了しており、後は専門的に詳しく説明します.
ここで説明したいのですが、Application ContectはBeanFactoryインターフェースを実現し、Resource Loader、Message Sourceなどのインターフェースを実現しており、強化されたBeanFactoryと考えられます.しかし、Apple Conteextは自分でBenFactoryの定義を繰り返し実現する方法ではなく、Default Listable BeanFactoryに委託して実現します.このような設計の構想も学習に値するのです.
後のprepareBenFactory()、postProcessiBenFactory()、invokeBenFactory PostProcessors()、register BenPostProcessors()、initMessage Source()、initAppliation EventMulticars()、オンライティング、Fastinestionsなどを追加します.いちいち詳しく話しません.
その中のキーポイントはfinish BenFactory Initializationです.この方法では先ほど登録したBean(遅延せずにロードします.)を実例化しますので、コアな方法です.
全体としての流れを紹介しました.次に、OutinFresh BeanFactoryの方法を重点的に見ます.上記で述べたように、この方法では、プロファイルのロード、解析、登録が完了しました.

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}
この方法は2つのことをして、まずrefshBenFactory()の方法によってDefault Listable BenFactoryの例を作成し、初期化する.そして戻ってきます

protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}
まずビーンファクトリーの例があるなら、まずクリアします.
そして、createBenFactory()方法によって、Default Listable BeanFactoryの例を作成します.

protected DefaultListableBeanFactory createBeanFactory() {
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());
	}
次にID固有IDを設定します.

beanFactory.setSerializationId(getId());
ユーザーにカスタマイズした設定を許可します.

protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		if (this.allowBeanDefinitionOverriding != null) {
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		if (this.allowCircularReferences != null) {
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
		beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
	}
最後に、コアのloadBenDefinitionsの方法です.

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// Configure the bean definition reader with this context's
		// resource loading environment.
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// Allow a subclass to provide custom initialization of the reader,
		// then proceed with actually loading the bean definitions.
		initBeanDefinitionReader(beanDefinitionReader);
		loadBeanDefinitions(beanDefinitionReader);
	}
ここではまずXmlBenDefinitionReaderの例を作成して初期化します.

// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// Configure the bean definition reader with this context's
		// resource loading environment.
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// Allow a subclass to provide custom initialization of the reader,
		// then proceed with actually loading the bean definitions.
		initBeanDefinitionReader(beanDefinitionReader);
ここで説明したいのですが、Application Contectは自分で構成ファイルのロード、解析、登録を担当していません.これらの仕事をXml BeanDefinitionReaderに委託します.

loadBeanDefinitions(beanDefinitionReader);
このコードは、ビーンが実際に発生したところを読むという定義です.ここの仕事は主にXmlBenDefinitionReaderで行います.次のブログではこの過程を詳しく紹介します.