Allow FrameworkServlet to be used as a bean

Change FrameworkServlet so that it can also be used as a bean within an
existing ApplicationContext. Primarily added to support use with
embedded servlet containers where Spring bootstraps the servlet
container, rather than the servlet container bootstrapping Spring.

Issue: SPR-10381
master
Phillip Webb 12 years ago
parent eaf8115d59
commit 19187fd365
  1. 36
      spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java

@ -21,6 +21,7 @@ import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.Callable;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@ -28,7 +29,9 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ApplicationListener;
@ -122,6 +125,7 @@ import org.springframework.web.util.WebUtils;
* @author Sam Brannen
* @author Chris Beams
* @author Rossen Stoyanchev
* @author Phillip Webb
* @see #doService
* @see #setContextClass
* @see #setContextConfigLocation
@ -129,7 +133,7 @@ import org.springframework.web.util.WebUtils;
* @see #setNamespace
*/
@SuppressWarnings("serial")
public abstract class FrameworkServlet extends HttpServletBean {
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {
/**
* Suffix for WebApplicationContext namespaces. If a servlet of this class is
@ -190,6 +194,9 @@ public abstract class FrameworkServlet extends HttpServletBean {
/** WebApplicationContext for this servlet */
private WebApplicationContext webApplicationContext;
/** If the WebApplicationContext was injected via {@link #setApplicationContext} */
private boolean webApplicationContextInjected = false;
/** Flag used to detect whether onRefresh has already been called */
private boolean refreshEventReceived = false;
@ -789,6 +796,9 @@ public abstract class FrameworkServlet extends HttpServletBean {
*/
@Override
public void destroy() {
if (this.webApplicationContextInjected) {
return;
}
getServletContext().log("Destroying Spring FrameworkServlet '" + getServletName() + "'");
if (this.webApplicationContext instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) this.webApplicationContext).close();
@ -1055,6 +1065,30 @@ public abstract class FrameworkServlet extends HttpServletBean {
return (userPrincipal != null ? userPrincipal.getName() : null);
}
/**
* Called by Spring via {@link ApplicationContextAware} to inject the current
* application context. This method allows FrameworkServlets to be registered as
* Spring Beans inside an existing {@link WebApplicationContext} rather than
* {@link #findWebApplicationContext() finding} a
* {@link org.springframework.web.context.ContextLoaderListener bootstrapped} context.
*
* <p>Primarily added to support use in embedded servlet containers, this method is not
* intended to be called directly.
*
* @since 4.0
*/
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
if (this.webApplicationContext == null
&& applicationContext instanceof WebApplicationContext) {
if (logger.isDebugEnabled()) {
logger.debug("Using existing application context for "
+ ClassUtils.getShortName(getClass()));
}
this.webApplicationContext = (WebApplicationContext) applicationContext;
this.webApplicationContextInjected = true;
}
}
/**
* Subclasses must implement this method to do the work of request handling,

Loading…
Cancel
Save