在查找错误时,我遇到了Spring 3.0.5源代码DelegatingFilterProxy
,我想知道它是否存在性能瓶颈。
鉴于每个Web应用程序只有一个DelegatingFilterProxy实例(当然是每个<filter>
声明)我必须假设在高负载下很多工作线程都试图调用doFilter()
方法并行。
现在看一下代码:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// Lazily initialize the delegate if necessary.
Filter delegateToUse = null;
synchronized (this.delegateMonitor) {
if (this.delegate == null) {
WebApplicationContext wac = findWebApplicationContext();
if (wac == null) {
throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?");
}
this.delegate = initDelegate(wac);
}
delegateToUse = this.delegate;
}
// Let the delegate perform the actual doFilter operation.
invokeDelegate(delegateToUse, request, response, filterChain);
}
synchronized (this.delegateMonitor)
块必须由所有线程传递,这意味着所有工作人员都被迫耐心排队,直到他们被允许进入。
无论为什么需要在这里完成bean查找,我怀疑可以避免使用synchronized
以支持并行执行 - 可能是通过使this.delegate
为volatile而仅使用同步需要完成查找的情况。
我在吠叫错误的树吗?任何意见都表示赞赏。
答案 0 :(得分:2)
你是对的 - 这似乎是一个潜在的问题,alghouth(正如拉尔夫所指出的那样),它应该不容易被人注意到。他们可以使用双重检查锁定(使用易失性委托)。
我建议你在春季jira中创建一个问题。如果你不这样做 - 我会做的。
答案 1 :(得分:1)
对我来说,它看起来像是一些初始化代码。第一次运行后this.delegate
的值与null
不同。然后,同步博客中只剩下两个if (this.delegate == null)
和delegateToUse = this.delegate
个数据。
每个请求执行一次此块,因此:NO它不会影响可以测量的Web应用程序的性能。
当然Bozho是对的,它可以做得更好。但是你永远不会注意到性能上的差异 - 如果服务器上有足够的负载使得这个sycronized块会产生可测量的影响,那么这个服务器上的其他任何东西都已经完全超载了。
答案 2 :(得分:1)
在Spring 4中通过双重检查修复了这个问题
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// Lazily initialize the delegate if necessary.
Filter delegateToUse = this.delegate;
if (delegateToUse == null) {
synchronized (this.delegateMonitor) {
if (this.delegate == null) {
WebApplicationContext wac = findWebApplicationContext();
if (wac == null) {
throw new IllegalStateException("No WebApplicationContext found: " +
"no ContextLoaderListener or DispatcherServlet registered?");
}
this.delegate = initDelegate(wac);
}
delegateToUse = this.delegate;
}
}
// Let the delegate perform the actual doFilter operation.
invokeDelegate(delegateToUse, request, response, filterChain);
}
见提交
https://github.com/spring-projects/spring-framework/commit/c26272cef62b1e6f3bb982d7f71b2f47c685b014
见JIRA https://jira.spring.io/browse/SPR-10413