← Назад к вопросам

Как долго существует контекст запроса, созданный DispatcherServlet

2.0 Middle🔥 141 комментариев
#Spring Boot и Spring Data#Spring Framework

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Жизненный цикл контекста запроса в DispatcherServlet

Временные рамки существования контекста

Контекст запроса, создаваемый DispatcherServlet в Spring Framework, существует на протяжении всего времени обработки одного HTTP запроса. Его жизненный цикл строго определен и охватывает период от момента, когда запрос поступает в сервлет, до момента, когда ответ полностью сформирован и отправлен клиенту.

Основные этапы жизненного цикла

1. Инициализация контекста (request scope)

Когда DispatcherServlet получает HTTP запрос, на уровне контейнера сервлета (Servlet API) создается объект RequestContext:

// Автоматически создается Spring в начале обработки
public class DispatcherServlet extends FrameworkServlet {
    @Override
    protected void doDispatch(HttpServletRequest request, 
                            HttpServletResponse response) throws Exception {
        // Здесь начинает существовать RequestContext
        RequestContextHolder.setRequestAttributes(
            new ServletRequestAttributes(request));
        try {
            // Обработка запроса
        } finally {
            // Контекст удаляется в finally блоке
            RequestContextHolder.resetRequestAttributes();
        }
    }
}

2. Доступность во время обработки

Контекст доступен во всех компонентах, участвующих в обработке запроса:

  • Controllers — имеют полный доступ
  • Services — могут получать текущий request через RequestContextHolder
  • Repositories — могут использовать request-scoped бины
  • Filters и Interceptors — видят и могут модифицировать контекст
@RestController
public class MyController {
    @GetMapping("/data")
    public ResponseEntity<?> getData() {
        // RequestContext доступен здесь
        HttpServletRequest request = 
            ((ServletRequestAttributes) RequestContextHolder
            .getRequestAttributes()).getRequest();
        return ResponseEntity.ok(request.getHeader("X-Custom-Header"));
    }
}

3. Завершение и очистка

Контекст удаляется в блоке finally после отправки ответа:

try {
    // Весь процесс обработки
    doDispatch(request, response);
} finally {
    // Очистка RequestContextHolder
    RequestContextHolder.resetRequestAttributes();
}

Практические последствия

Request-scoped бины

Бины с областью видимости request создаются один раз за жизненный цикл контекста:

@Configuration
public class RequestScopeConfig {
    @Bean
    @Scope(value = WebApplicationContext.SCOPE_REQUEST, 
           proxyMode = ScopedProxyMode.TARGET_CLASS)
    public RequestMetadata requestMetadata() {
        return new RequestMetadata();
    }
}

ThreadLocal хранилище

Spring использует ThreadLocal для хранения RequestContext, что обеспечивает thread-safe доступ:

public abstract class RequestContextHolder {
    private static final ThreadLocal<RequestAttributes> requestAttributesHolder =
        new NamedThreadLocal<>("Request attributes");
    
    public static RequestAttributes getRequestAttributes() {
        RequestAttributes attributes = requestAttributesHolder.get();
        if (attributes == null) {
            throw new IllegalStateException(
                "No thread-bound request found");
        }
        return attributes;
    }
}

Асинхронные запросы (Async/Await)

Для асинхронных операций поведение отличается:

@GetMapping("/async")
public CompletableFuture<String> asyncRequest() {
    // Контекст сохраняется для асинхронной операции
    return CompletableFuture.supplyAsync(() -> {
        // RequestContext может быть недоступен здесь
        // без дополнительной настройки
        return "result";
    });
}

Для асинхронных операций нужно явно сохранять и восстанавливать контекст.

Выводы

  1. Время жизни: Контекст существует от начала обработки HTTP запроса до отправки полного ответа
  2. Область видимости: Ограничен одним HTTP запросом и одним потоком (в стандартном Tomcat)
  3. Автоматическое управление: Spring полностью управляет созданием и удалением контекста
  4. Thread-safe: Реализовано через ThreadLocal, безопасно в многопоточной среде
  5. Важно для разработчика: Помнить, что request-scoped компоненты недоступны за пределами обработки запроса