При поиске ошибок я наткнулся на исходный код Spring 3.0.5 DelegatingFilterProxy
, и мне интересно, несет ли он узкое место в производительности или нет.
Учитывая, что для каждого веб-приложения существует только один экземпляр 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 и использовать только синхронизациюв случае необходимости поиска.
Так я лаю не на том дереве?Любой вклад приветствуется.