>  기사  >  Java  >  Spring 웹 시작 시 IOC 소스 코드 분석

Spring 웹 시작 시 IOC 소스 코드 분석

高洛峰
高洛峰원래의
2017-03-12 09:40:081531검색

본 글은 spring web 구동시 IOC 소스코드에 대한 연구를 분석한 글이다

  1. IOC를 공부하려면 먼저 web에서 간단한 웹 프로젝트를 만들어보자.xml

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

문장을 추가하겠습니다. 이는 웹 컨테이너가 시작될 때 먼저 ContextLoaderListener 클래스에 들어간 다음 이를 로드한다는 의미입니다. 클래스 경로 applicationContext.xml 파일에 있습니다. 그런 다음 ContextLoaderListener에 초점을 맞추고 오픈 소스 코드인

/**
     * Initialize the root web application context.     */
    @Override    public void contextInitialized(ServletContextEvent event) {
        initWebApplicationContext(event.getServletContext());
    }    /**
     * Close the root web application context.     */
    @Override    public void contextDestroyed(ServletContextEvent event) {
        closeWebApplicationContext(event.getServletContext());
        ContextCleanupListener.cleanupAttributes(event.getServletContext());
    }

를 클릭합니다. 여기에는 주로 ServletContextListener인터페이스의 두 가지 구현 방법이 포함되어 있습니다. 웹 컨테이너는 먼저 contextInitialized 메서드를 호출하고 tomcat으로 캡슐화된 컨테이너 리소스를 전달한 다음 상위 클래스의 초기화 컨테이너 메서드를 호출합니다.

/*** The root WebApplicationContext instance that this loader manages.*/private WebApplicationContext context;public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
      ...........省略// Store context in local instance variable, to guarantee that            // it is available on ServletContext shutdown.
            if (this.context == null) {                this.context = createWebApplicationContext(servletContext);
            }            if (this.context instanceof ConfigurableWebApplicationContext) {
                ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;                if (!cwac.isActive()) {                    // The context has not yet been refreshed -> provide services such as                    // setting the parent context, setting the application context id, etc
                    if (cwac.getParent() == null) {                        // The context instance was injected without an explicit parent ->                        // determine parent for root web application context, if any.
                        ApplicationContext parent = loadParentContext(servletContext);
                        cwac.setParent(parent);
                    }
                    configureAndRefreshWebApplicationContext(cwac, servletContext);
                }
            }
            servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);

            ClassLoader ccl = Thread.currentThread().getContextClassLoader();            if (ccl == ContextLoader.class.getClassLoader()) {
                currentContext = this.context;
            }            else if (ccl != null) {
                currentContextPerThread.put(ccl, this.context);
            }
  ......省略            return this.context;
        
    }

이 메서드의 주요 단계는 XmlWebApplicationContext의 루트 컨테이너를 만드는 데 사용되는 createWebApplicationContext 메서드입니다. 이 컨테이너는 servletContextEvent에서 가져옵니다.

loadParentContext 메소드는 상위 컨테이너를 로드하는 데 사용됩니다. 기본 메소드인configureAndRefreshWebApplicationContext는 루트 컨테이너를 구성하고 새로 고치는 데 사용됩니다. 메소드 내에서 가장 중요한 메소드는 가장 중요한 기능을 구현하는 새로 고침 메소드입니다.

@Override    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) {
                logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);                // Destroy already created singletons to avoid dangling resources.                destroyBeans();                // Reset &#39;active&#39; flag.                cancelRefresh(ex);                // Propagate exception to caller.
                throw ex;
            }
        }
    }

prepareRefresh 메소드는 나중에 사용할 환경을 준비하는 데 사용됩니다.

obtainFreshBeanFactory 메소드는 beanFactory를 얻습니다

@Override    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);
        }
    }

실제 반환된 beanFactory는 나중에 xml을 로드하는 데 사용하기 위해 인스턴스화되는 구현 클래스 DefaultListableBeanFactory입니다. 수업.

loadBeanDefinitions는 실제로 클래스를 로드하는 데 사용되는 중요한 메소드입니다. 이전의 메소드는 모두 준비 작업이었습니다.


위 내용은 Spring 웹 시작 시 IOC 소스 코드 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.