스프링 소스 분석 (1) XmlWebapplicationContext

spring 은 누구나 사용 할 수 있 는 ioc 프레임 워 크 입 니 다. 하지만 spring 을 정말 이해 하려 면 잘 연구 해 야 합 니 다. 이 를 위해 spring 소스 코드 를 보 았 기 때문에 spring 소스 코드 분석 글 을 쓰기 시 작 했 습 니 다. 이것 은 첫 번 째 편 입 니 다. 먼저 ioc 용기 의 작 동 부터 시작 합 니 다.spring 의 ioc 용기 의 가장 기본 적 인 인 터 페 이 스 는 BeanFactory 라 는 것 을 잘 알 고 있 습 니 다. Application Context 는 BeanFactory 의 모든 정 보 를 포함 하고 있 기 때문에 ioc 용기 가 작 동 할 때 AbstractApplication Context 의 refresh 방법 에서 시 작 됩 니 다.
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) { //   ,   #refresh()   #close()   ,          。
        // Prepare this context for refreshing.
        //         
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        //     BeanFactory ,    XML     
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        //   BeanFactory         。
        // TODO     @Autowired   @Qualifier        
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            //        ,  BeanFactory       
            postProcessBeanFactory(beanFactory);
            // Invoke factory processors registered as beans in the context.
            //      BeanFactory    ,   BeanFactoryPostProcessor
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            //      Bean     BeanPostProcessor。      ,       #getBean(...)   ,  Bean      。
            //   :
            //      1. BeanFactoryPostProcessor     BeanDefinition
            //      2. BeanPostProcessor     Bean
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            initMessageSource();

            // Initialize event multicaster for this context.
            //     Application Event Multicaster
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            //     ,          Bean    
            onRefresh();

            // Check for listener beans and register them.
            //       
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            //            
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            //    refresh   
            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();
        }
    }
}

구체 적 인 시작 절 차 는 말 하지 않 겠 습 니 다. 주로 여기 서 onRefresh 방법 이 있 습 니 다. 우 리 는 AbstractRefreshable WebApplication Context 라 는 종 류 를 살 펴 보 겠 습 니 다. 이 종류 에 onRefresh 방법 을 복 사 했 습 니 다.
protected void onRefresh() {
    this.themeSource = UiApplicationContextUtils.initThemeSource(this);
}

이것 은 무엇 입 니까?서 두 르 지 마 세 요. themeSource 가 무엇 인지 봅 시다.
public static ThemeSource initThemeSource(ApplicationContext context) {
    if (context.containsLocalBean(THEME_SOURCE_BEAN_NAME)) {
        ThemeSource themeSource = context.getBean(THEME_SOURCE_BEAN_NAME, ThemeSource.class);
        // Make ThemeSource aware of parent ThemeSource.
        if (context.getParent() instanceof ThemeSource && themeSource instanceof HierarchicalThemeSource) {
            HierarchicalThemeSource hts = (HierarchicalThemeSource) themeSource;
            if (hts.getParentThemeSource() == null) {
                // Only set parent context as parent ThemeSource if no parent ThemeSource
                // registered already.
                hts.setParentThemeSource((ThemeSource) context.getParent());
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Using ThemeSource [" + themeSource + "]");
        }
        return themeSource;
    }
    else {
        // Use default ThemeSource to be able to accept getTheme calls, either
        // delegating to parent context's default or to local ResourceBundleThemeSource.
        HierarchicalThemeSource themeSource = null;
        if (context.getParent() instanceof ThemeSource) {
            themeSource = new DelegatingThemeSource();
            themeSource.setParentThemeSource((ThemeSource) context.getParent());
        }
        else {
            themeSource = new ResourceBundleThemeSource();
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate ThemeSource with name '" + THEME_SOURCE_BEAN_NAME +
                    "': using default [" + themeSource + "]");
        }
        return themeSource;
    }
}

아니면 잘 모 르 겠 어 요?그럼 Abstract Refreshable WebapplicationContext 의 구 조 를 살 펴 보 겠 습 니 다.
public abstract class AbstractRefreshableWebApplicationContext extends AbstractRefreshableConfigApplicationContext
    implements ConfigurableWebApplicationContext, ThemeSource

원래 ThemeSource 는 하나의 인터페이스 이 고 AbstractRefreshable WebApplication Context 는 이 인 터 페 이 스 를 실현 하여 onRefresh 에서 자신 을 들 여 보 냈 습 니 다. 알 겠 습 니 다. 이것 은 먼저 여 기 를 보 겠 습 니 다.우 리 는 XmlWebApplication Context 라 는 클래스 에 직접 가서 Abstract Refreshable Application Context 류 에 loadBean Definitions 가 있 는 것 을 발 견 했 습 니 다. 그리고 XmlWebApplication Context 는 이 방법 을 복 사 했 습 니 다. 우 리 는 XmlWebApplication Context 가 어떻게 실현 되 는 지 보 겠 습 니 다.
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(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);
}

ioc 용기 에 있 는 인터페이스 BeanDefinitionReader 를 소개 합 니 다. XmlBeanDefinitionReader 는 BeanDefinitionReader 의 구현 클래스 로 xml 설정 파일 을 읽 고 ioc 용기 에 넣 습 니 다.설정 파일 을 읽 은 후, loadBeanDefinitions 방법 을 통 해 bean 을 ioc 용기 에 등록 합 니 다.
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
        for (String configLocation : configLocations) {
            reader.loadBeanDefinitions(configLocation);
        }
    }
}

이로써 ioc 용기 가 작 동 됩 니 다.XmlWebApplication Context 의 분석 은 여기까지 입 니 다.

좋은 웹페이지 즐겨찾기