DelegatingFilterProxy avoids synchronization for pre-resolved delegate

Issue: SPR-10413
This commit is contained in:
Juergen Hoeller 2013-08-02 18:17:13 +02:00
parent fdaf7eb78a
commit c26272cef6
1 changed files with 14 additions and 17 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2013 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -88,7 +88,7 @@ public class DelegatingFilterProxy extends GenericFilterBean {
private boolean targetFilterLifecycle = false; private boolean targetFilterLifecycle = false;
private Filter delegate; private volatile Filter delegate;
private final Object delegateMonitor = new Object(); private final Object delegateMonitor = new Object();
@ -227,7 +227,6 @@ public class DelegatingFilterProxy extends GenericFilterBean {
if (this.targetBeanName == null) { if (this.targetBeanName == null) {
this.targetBeanName = getFilterName(); this.targetBeanName = getFilterName();
} }
// Fetch Spring root application context and initialize the delegate early, // Fetch Spring root application context and initialize the delegate early,
// if possible. If the root application context will be started after this // if possible. If the root application context will be started after this
// filter proxy, we'll have to resort to lazy initialization. // filter proxy, we'll have to resort to lazy initialization.
@ -244,16 +243,18 @@ public class DelegatingFilterProxy extends GenericFilterBean {
throws ServletException, IOException { throws ServletException, IOException {
// Lazily initialize the delegate if necessary. // Lazily initialize the delegate if necessary.
Filter delegateToUse = null; Filter delegateToUse = this.delegate;
synchronized (this.delegateMonitor) { if (delegateToUse == null) {
if (this.delegate == null) { synchronized (this.delegateMonitor) {
WebApplicationContext wac = findWebApplicationContext(); if (this.delegate == null) {
if (wac == null) { WebApplicationContext wac = findWebApplicationContext();
throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?"); if (wac == null) {
throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?");
}
this.delegate = initDelegate(wac);
} }
this.delegate = initDelegate(wac); delegateToUse = this.delegate;
} }
delegateToUse = this.delegate;
} }
// Let the delegate perform the actual doFilter operation. // Let the delegate perform the actual doFilter operation.
@ -262,10 +263,7 @@ public class DelegatingFilterProxy extends GenericFilterBean {
@Override @Override
public void destroy() { public void destroy() {
Filter delegateToUse = null; Filter delegateToUse = this.delegate;
synchronized (this.delegateMonitor) {
delegateToUse = this.delegate;
}
if (delegateToUse != null) { if (delegateToUse != null) {
destroyDelegate(delegateToUse); destroyDelegate(delegateToUse);
} }
@ -282,8 +280,7 @@ public class DelegatingFilterProxy extends GenericFilterBean {
* {@code ServletContext} before this filter gets initialized (or invoked). * {@code ServletContext} before this filter gets initialized (or invoked).
* <p>Subclasses may override this method to provide a different * <p>Subclasses may override this method to provide a different
* {@code WebApplicationContext} retrieval strategy. * {@code WebApplicationContext} retrieval strategy.
* @return the {@code WebApplicationContext} for this proxy, or {@code null} if not * @return the {@code WebApplicationContext} for this proxy, or {@code null} if not found
* found
* @see #DelegatingFilterProxy(String, WebApplicationContext) * @see #DelegatingFilterProxy(String, WebApplicationContext)
* @see #getContextAttribute() * @see #getContextAttribute()
* @see WebApplicationContextUtils#getWebApplicationContext(javax.servlet.ServletContext) * @see WebApplicationContextUtils#getWebApplicationContext(javax.servlet.ServletContext)