Почему аннотации запросов в Spring-контроллерах работают только с public-методами?

«Почему аннотации запросов в Spring-контроллерах работают только с public-методами?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Аннотации, такие как @GetMapping или @PostMapping, работают только с public-методами из-за механизма работы Spring AOP (Aspect-Oriented Programming).

Причины:

  1. Проксирование: Spring создаёт динамические прокси (JDK или CGLIB) вокруг бинов-контроллеров для обработки запросов, валидации, транзакций и т.д. Прокси может вызывать только public-методы целевого объекта.
  2. Ограничения рефлексии: Даже если бы Spring использовал чистую рефлексию, вызов private или protected методов потребовал бы установки прав доступа (setAccessible(true)), что противоречит стандартной семантике и безопасности фреймворка.

Пример:

@RestController
public class ExampleController {
    // Работает: метод публичный, прокси может его вызвать.
    @GetMapping("/ok")
    public String publicHandler() {
        return "Success";
    }

    // Не работает: Spring проигнорирует этот метод.
    // Запрос на /fail вызовет 404 (Not Found) или 405 (Method Not Allowed).
    @GetMapping("/fail")
    private String privateHandler() {
        return "This will never be reached";
    }
}

Вывод: Ограничение на public методы обеспечивает корректную работу прокси-механизмов Spring и соответствует принципам проектирования контроллеров как публичного API.