Introduce DelegatingFilterProxy constructors
Issue: SPR-7672
This commit is contained in:
@@ -23,6 +23,8 @@ import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
|
||||
@@ -50,22 +52,38 @@ import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
* of the {@code Filter.init} and {@code Filter.destroy} lifecycle methods
|
||||
* on the target bean, letting the servlet container manage the filter lifecycle.
|
||||
*
|
||||
* <p>This class is inspired by Acegi Security's FilterToBeanProxy class,
|
||||
* written by Ben Alex.
|
||||
* <p>As of Spring 3.1, {@code DelegatingFilterProxy} has been updated to optionally accept
|
||||
* constructor parameters when using Servlet 3.0's instance-based filter registration
|
||||
* methods, usually in conjunction with Spring 3.1's
|
||||
* {@link org.springframework.web.WebApplicationInitializer} SPI. These constructors allow
|
||||
* for providing the delegate Filter bean directly, or providing the application context
|
||||
* and bean name to fetch, avoiding the need to look up the application context from the
|
||||
* ServletContext.
|
||||
*
|
||||
* <p>This class was originally inspired by Spring Security's {@code FilterToBeanProxy}
|
||||
* class, written by Ben Alex.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @author Chris Beams
|
||||
* @since 1.2
|
||||
* @see #setTargetBeanName
|
||||
* @see #setTargetFilterLifecycle
|
||||
* @see javax.servlet.Filter#doFilter
|
||||
* @see javax.servlet.Filter#init
|
||||
* @see javax.servlet.Filter#destroy
|
||||
* @see #DelegatingFilterProxy(Filter)
|
||||
* @see #DelegatingFilterProxy(String)
|
||||
* @see #DelegatingFilterProxy(String, WebApplicationContext)
|
||||
* @see javax.servlet.ServletContext#addFilter(String, Filter)
|
||||
* @see org.springframework.web.WebApplicationInitializer
|
||||
*/
|
||||
public class DelegatingFilterProxy extends GenericFilterBean {
|
||||
|
||||
private String contextAttribute;
|
||||
|
||||
private WebApplicationContext webApplicationContext;
|
||||
|
||||
private String targetBeanName;
|
||||
|
||||
private boolean targetFilterLifecycle = false;
|
||||
@@ -75,6 +93,78 @@ public class DelegatingFilterProxy extends GenericFilterBean {
|
||||
private final Object delegateMonitor = new Object();
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code DelegatingFilterProxy}. For traditional (pre-Servlet 3.0) use
|
||||
* in {@code web.xml}.
|
||||
* @see #setTargetBeanName(String)
|
||||
*/
|
||||
public DelegatingFilterProxy() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code DelegatingFilterProxy} with the given {@link Filter} delegate.
|
||||
* Bypasses entirely the need for interacting with a Spring application context,
|
||||
* specifying the {@linkplain #setTargetBeanName target bean name}, etc.
|
||||
* <p>For use in Servlet 3.0+ environments where instance-based registration of
|
||||
* filters is supported.
|
||||
* @param delegate the {@code Filter} instance that this proxy will delegate to and
|
||||
* manage the lifecycle for (must not be {@code null}).
|
||||
* @see #doFilter(ServletRequest, ServletResponse, FilterChain)
|
||||
* @see #invokeDelegate(Filter, ServletRequest, ServletResponse, FilterChain)
|
||||
* @see #destroy()
|
||||
* @see #setEnvironment(org.springframework.core.env.Environment)
|
||||
*/
|
||||
public DelegatingFilterProxy(Filter delegate) {
|
||||
Assert.notNull(delegate, "delegate Filter object must not be null");
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code DelegatingFilterProxy} that will retrieve the named target
|
||||
* bean from the Spring {@code WebApplicationContext} found in the {@code ServletContext}
|
||||
* (either the 'root' application context or the context named by
|
||||
* {@link #setContextAttribute}).
|
||||
* <p>For use in Servlet 3.0+ environments where instance-based registration of
|
||||
* filters is supported.
|
||||
* <p>The target bean must implement the standard Servlet Filter.
|
||||
* @param targetBeanName name of the target filter bean to look up in the Spring
|
||||
* application context (must not be {@code null}).
|
||||
* @see #findWebApplicationContext()
|
||||
* @see #setEnvironment(org.springframework.core.env.Environment)
|
||||
*/
|
||||
public DelegatingFilterProxy(String targetBeanName) {
|
||||
this(targetBeanName, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code DelegatingFilterProxy} that will retrieve the named target
|
||||
* bean from the given Spring {@code WebApplicationContext}.
|
||||
* <p>For use in Servlet 3.0+ environments where instance-based registration of
|
||||
* filters is supported.
|
||||
* <p>The target bean must implement the standard Servlet Filter interface.
|
||||
* <p>The given {@code WebApplicationContext} may or may not be refreshed when passed
|
||||
* in. If it has not, and if the context implements {@link ConfigurableApplicationContext},
|
||||
* a {@link ConfigurableApplicationContext#refresh() refresh()} will be attempted before
|
||||
* retrieving the named target bean.
|
||||
* <p>This proxy's {@code Environment} will be inherited from the given
|
||||
* {@code WebApplicationContext}.
|
||||
* @param targetBeanName name of the target filter bean in the Spring application
|
||||
* context (must not be {@code null}).
|
||||
* @param wac the application context from which the target filter will be retrieved;
|
||||
* if {@code null}, an application context will be looked up from {@code ServletContext}
|
||||
* as a fallback.
|
||||
* @see #findWebApplicationContext()
|
||||
* @see #setEnvironment(org.springframework.core.env.Environment)
|
||||
*/
|
||||
public DelegatingFilterProxy(String targetBeanName, WebApplicationContext wac) {
|
||||
Assert.hasText(targetBeanName, "target Filter bean name must not be null or empty");
|
||||
this.setTargetBeanName(targetBeanName);
|
||||
this.webApplicationContext = wac;
|
||||
if (wac != null) {
|
||||
this.setEnvironment(wac.getEnvironment());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the ServletContext attribute which should be used to retrieve the
|
||||
* {@link WebApplicationContext} from which to load the delegate {@link Filter} bean.
|
||||
@@ -131,18 +221,20 @@ public class DelegatingFilterProxy extends GenericFilterBean {
|
||||
|
||||
@Override
|
||||
protected void initFilterBean() throws ServletException {
|
||||
// If no target bean name specified, use filter name.
|
||||
if (this.targetBeanName == null) {
|
||||
this.targetBeanName = getFilterName();
|
||||
}
|
||||
|
||||
// Fetch Spring root application context and initialize the delegate early,
|
||||
// if possible. If the root application context will be started after this
|
||||
// filter proxy, we'll have to resort to lazy initialization.
|
||||
synchronized (this.delegateMonitor) {
|
||||
WebApplicationContext wac = findWebApplicationContext();
|
||||
if (wac != null) {
|
||||
this.delegate = initDelegate(wac);
|
||||
if (this.delegate == null) {
|
||||
// If no target bean name specified, use filter name.
|
||||
if (this.targetBeanName == null) {
|
||||
this.targetBeanName = getFilterName();
|
||||
}
|
||||
|
||||
// Fetch Spring root application context and initialize the delegate early,
|
||||
// if possible. If the root application context will be started after this
|
||||
// filter proxy, we'll have to resort to lazy initialization.
|
||||
WebApplicationContext wac = findWebApplicationContext();
|
||||
if (wac != null) {
|
||||
this.delegate = initDelegate(wac);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -180,16 +272,33 @@ public class DelegatingFilterProxy extends GenericFilterBean {
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve a <code>WebApplicationContext</code> from the <code>ServletContext</code>
|
||||
* attribute with the {@link #setContextAttribute configured name}. The
|
||||
* <code>WebApplicationContext</code> must have already been loaded and stored in the
|
||||
* <code>ServletContext</code> before this filter gets initialized (or invoked).
|
||||
* Return the {@code WebApplicationContext} passed in at construction time, if available.
|
||||
* Otherwise, attempt to retrieve a {@code WebApplicationContext} from the
|
||||
* {@code ServletContext} attribute with the {@linkplain #setContextAttribute
|
||||
* configured name} if set. Otherwise look up a {@code WebApplicationContext} under
|
||||
* the well-known "root" application context attribute. The
|
||||
* {@code WebApplicationContext} must have already been loaded and stored in the
|
||||
* {@code ServletContext} before this filter gets initialized (or invoked).
|
||||
* <p>Subclasses may override this method to provide a different
|
||||
* <code>WebApplicationContext</code> retrieval strategy.
|
||||
* @return the WebApplicationContext for this proxy, or <code>null</code> if not found
|
||||
* {@code WebApplicationContext} retrieval strategy.
|
||||
* @return the {@code WebApplicationContext} for this proxy, or {@code null} if not
|
||||
* found
|
||||
* @see #DelegatingFilterProxy(String, WebApplicationContext)
|
||||
* @see #getContextAttribute()
|
||||
* @see WebApplicationContextUtils#getWebApplicationContext(javax.servlet.ServletContext)
|
||||
* @see WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
|
||||
*/
|
||||
protected WebApplicationContext findWebApplicationContext() {
|
||||
if (this.webApplicationContext != null) {
|
||||
// the user has injected a context at construction time -> use it
|
||||
if (this.webApplicationContext instanceof ConfigurableApplicationContext) {
|
||||
if (!((ConfigurableApplicationContext)this.webApplicationContext).isActive()) {
|
||||
// the context has not yet been refreshed -> do so before returning it
|
||||
((ConfigurableApplicationContext)this.webApplicationContext).refresh();
|
||||
}
|
||||
}
|
||||
return this.webApplicationContext;
|
||||
}
|
||||
String attrName = getContextAttribute();
|
||||
if (attrName != null) {
|
||||
return WebApplicationContextUtils.getWebApplicationContext(getServletContext(), attrName);
|
||||
|
||||
Reference in New Issue
Block a user