Spring ContextLoaderListener 中WebApplicationContext初始化

    在spring和structs2整合中,在web.xml文件中需要設置一個listener,如下

    

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

    ContextLoaderListener會在web容器初始化的時候進行初始化,然後進行初始化WebApplicationContext的工作。我們來看一下ContextLoaderListener的關鍵代碼:

    

    public void contextInitialized(ServletContextEvent event) {
        this.contextLoader = createContextLoader();
        if (this.contextLoader == null) {
            this.contextLoader = this;
        }
        this.contextLoader.initWebApplicationContext(event.getServletContext());
    }

        這段代碼實現了WebApplicationContext初始化工作,在代碼的最後一行調用了contextLoader的initWebApplicationContext的方法,我們再來看一下contextLoader的initWebApplicationContext方法的關鍵代碼:

    public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
        if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
            throw new IllegalStateException(
                    "Cannot initialize context because there is already a root application context present - " +
                    "check whether you have multiple ContextLoader* definitions in your web.xml!");
        }
        Log logger = LogFactory.getLog(ContextLoader.class);
        servletContext.log("Initializing Spring root WebApplicationContext");
        if (logger.isInfoEnabled()) {
            logger.info("Root WebApplicationContext: initialization started");
        }
        long startTime = System.currentTimeMillis();
        try {
            // Store context in local instance variable, to guarantee that
            // it is available on ServletContext shutdown.
            if (this.context == null) {
                this.context = createWebApplicationContext(servletContext);
            }

最後一行,又調用了createWebApplicationContext方法,我們再來看一下這個方法的代碼:

    protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
        Class<?> contextClass = determineContextClass(sc);
        if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
            throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
                    "] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
        }
        return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
    }

通過代碼可知,在這裏返回了一個ConfigurableWebApplicationContext,再來看一下contextLoader的initWebApplicationContext方法中最關鍵的代碼:

servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);

在這裏把context存入servletContext中,所以以後要用到WebApplicationContext的時候可以從servletContext取出。

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