Почему @Async и приватный метод — рабочий код до первого вызова

Этим вопросом проверяют, понимает ли кандидат, как Spring вообще применяет AOP-аннотации, а не просто помнит слово «прокси».

@Async, как и @Transactional, работает через проксирование бина. Spring оборачивает объект прокси-обёрткой, которая перехватывает вызов метода снаружи и решает, выполнять его в текущем потоке или отправить в пул. Приватный метод перехватить нельзя — прокси не видит вызовы, происходящие внутри самого объекта.

Пометить приватный метод @Async компилятор разрешит без единой ошибки. Аннотация просто не будет иметь эффекта: метод выполнится синхронно, в том же потоке, что и вызывающий код.

@Service public class ReportService {

public void generate() { buildAsync(); }

@Async private void buildAsync() { // выполнится синхронно, // аннотация проигнорирована } }

Дальше спросят: а если сделать метод public, но вызвать его через this внутри того же класса? Ответ тот же — не сработает, потому что вызов идёт напрямую к целевому объекту, минуя прокси. Асинхронность появится только если вызвать метод через инжектированную ссылку на бин снаружи или через self-injection.

@Async без внешнего вызова — это метод, который выглядит асинхронным в коде и синхронным в runtime.

Тренажёр: 600 вопросов, мок с таймером, план повторов

senior·base — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки