Почему @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 — что спрашивают на самом деле
В этом посте были ссылки, но мы их удалили по правилам Сетки