001/*
002 * Copyright 2002-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.web.context;
018
019import javax.servlet.ServletContextEvent;
020import javax.servlet.ServletContextListener;
021
022/**
023 * Bootstrap listener to start up and shut down Spring's root {@link WebApplicationContext}.
024 * Simply delegates to {@link ContextLoader} as well as to {@link ContextCleanupListener}.
025 *
026 * <p>As of Spring 3.1, {@code ContextLoaderListener} supports injecting the root web
027 * application context via the {@link #ContextLoaderListener(WebApplicationContext)}
028 * constructor, allowing for programmatic configuration in Servlet 3.0+ environments.
029 * See {@link org.springframework.web.WebApplicationInitializer} for usage examples.
030 *
031 * @author Juergen Hoeller
032 * @author Chris Beams
033 * @since 17.02.2003
034 * @see #setContextInitializers
035 * @see org.springframework.web.WebApplicationInitializer
036 */
037public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
038
039        /**
040         * Create a new {@code ContextLoaderListener} that will create a web application
041         * context based on the "contextClass" and "contextConfigLocation" servlet
042         * context-params. See {@link ContextLoader} superclass documentation for details on
043         * default values for each.
044         * <p>This constructor is typically used when declaring {@code ContextLoaderListener}
045         * as a {@code <listener>} within {@code web.xml}, where a no-arg constructor is
046         * required.
047         * <p>The created application context will be registered into the ServletContext under
048         * the attribute name {@link WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE}
049         * and the Spring application context will be closed when the {@link #contextDestroyed}
050         * lifecycle method is invoked on this listener.
051         * @see ContextLoader
052         * @see #ContextLoaderListener(WebApplicationContext)
053         * @see #contextInitialized(ServletContextEvent)
054         * @see #contextDestroyed(ServletContextEvent)
055         */
056        public ContextLoaderListener() {
057        }
058
059        /**
060         * Create a new {@code ContextLoaderListener} with the given application context. This
061         * constructor is useful in Servlet 3.0+ environments where instance-based
062         * registration of listeners is possible through the {@link javax.servlet.ServletContext#addListener}
063         * API.
064         * <p>The context may or may not yet be {@linkplain
065         * org.springframework.context.ConfigurableApplicationContext#refresh() refreshed}. If it
066         * (a) is an implementation of {@link ConfigurableWebApplicationContext} and
067         * (b) has <strong>not</strong> already been refreshed (the recommended approach),
068         * then the following will occur:
069         * <ul>
070         * <li>If the given context has not already been assigned an {@linkplain
071         * org.springframework.context.ConfigurableApplicationContext#setId id}, one will be assigned to it</li>
072         * <li>{@code ServletContext} and {@code ServletConfig} objects will be delegated to
073         * the application context</li>
074         * <li>{@link #customizeContext} will be called</li>
075         * <li>Any {@link org.springframework.context.ApplicationContextInitializer ApplicationContextInitializer org.springframework.context.ApplicationContextInitializer ApplicationContextInitializers}
076         * specified through the "contextInitializerClasses" init-param will be applied.</li>
077         * <li>{@link org.springframework.context.ConfigurableApplicationContext#refresh refresh()} will be called</li>
078         * </ul>
079         * If the context has already been refreshed or does not implement
080         * {@code ConfigurableWebApplicationContext}, none of the above will occur under the
081         * assumption that the user has performed these actions (or not) per his or her
082         * specific needs.
083         * <p>See {@link org.springframework.web.WebApplicationInitializer} for usage examples.
084         * <p>In any case, the given application context will be registered into the
085         * ServletContext under the attribute name {@link
086         * WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE} and the Spring
087         * application context will be closed when the {@link #contextDestroyed} lifecycle
088         * method is invoked on this listener.
089         * @param context the application context to manage
090         * @see #contextInitialized(ServletContextEvent)
091         * @see #contextDestroyed(ServletContextEvent)
092         */
093        public ContextLoaderListener(WebApplicationContext context) {
094                super(context);
095        }
096
097
098        /**
099         * Initialize the root web application context.
100         */
101        @Override
102        public void contextInitialized(ServletContextEvent event) {
103                initWebApplicationContext(event.getServletContext());
104        }
105
106
107        /**
108         * Close the root web application context.
109         */
110        @Override
111        public void contextDestroyed(ServletContextEvent event) {
112                closeWebApplicationContext(event.getServletContext());
113                ContextCleanupListener.cleanupAttributes(event.getServletContext());
114        }
115
116}