高級容器Application Contectの初期過程---総覧と概要


SpringとしてのIoCの最も核心的な部分は「容器」という概念であり、全てのbeanの定義とbean間の可能な相互依存関係を統一的に管理するために使われています.Springでは、容器はベース容器と高級容器に分けられ、BenFactoryはSpringの最下層のコアとして実現され、Springの基礎のように、Springの基本的な機能:beanの管理を提供しています.アプレックスはBeanFactoryの拡大(BeanFactoryから継承)であり、より豊富な機能を提供しています.国際的な資源訪問、イベントの普及メカニズムなど、日常的に働く中開発のSpring企業に対しても、基本的にApplication Contactをベースにしていますので、Application Contextの原理と実現を把握することが重要です.次はApplication Contectの下の階の実現について深く理解します.
    Application Comptextは高級容器インターフェースとして、多くの一般的な実装クラスがあります.例えば、FileSystemXmlApplication ComptextとClass PathXml Application Comptextは、それらはすべてAbstractXml Aplication Context抽象類(Application Contextインターフェイスがベースクラスを実現します)に継承します.まず、FileSystemXmlAppleication Contectで構成ファイルを読み込むという例を挙げて、このクラスはどのように一歩ずつ初期化が完了しているかを確認します.
 ApplicationContext ac=new FileSystemXmlApplicationContext("myApplicationContextTest.xml");
FileSystemXmlAppliation Conteet類に入り、構造過程を見てください.
public FileSystemXmlApplicationContext(String configLocation) throws BeansException {
        this(new String[] {configLocation}, true, null);
    }
    
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
            throws BeansException {
        super(parent);
        setConfigLocations(configLocations);//      
        if (refresh) {
            refresh();//        
        }
    }
setConfigLocationsを追跡する方法は、Abstract Refresheble ConfigAppliation Controtext類に入ることで、実現方法は以下の通りである.
public void setConfigLocations(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()方法の実現を重点的に見てみます.この方法は基本的な核心抽象類AbstractAplicationControtextにカプセル化されています.
@Override
public void refresh() throws BeansException, IllegalStateException {
	    synchronized (this.startupShutdownMonitor) { //   ,           
			//           ,                 
			prepareRefresh();

			//    beanfactory,   XML    
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			//  beanfactory   ,        ,SPEL       ,       
			prepareBeanFactory(beanFactory);

			try {
				//      ,           ,        request/session     servlet     
				postProcessBeanFactory(beanFactory);

				//     beanfactory   
				invokeBeanFactoryPostProcessors(beanFactory);

				//     bean   bean   
				registerBeanPostProcessors(beanFactory);

				//    message   ,     ,     
				initMessageSource();

				//           
				initApplicationEventMulticaster();

				//       ,     bean    
				onRefresh();

				//  bean   ,          
				registerListeners();

				//                bean
				finishBeanFactoryInitialization(beanFactory);

				//     ,      ,              
				finishRefresh();
			}

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

				//          bean
				destroyBeans();

				//  active  
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				//        
				resetCommonCaches();
			}
		}
   }
ここから分かるように、高級容器Application Contectの初期化過程のコード構造は非常にはっきりしていて、私達が想像していたほど難しくはありません.以下は上述の初期化の全体的な流れに沿って、引き続き深く入り込みます.各ステップの具体的な仕事もそんなに簡単ではないことが分かります.