Вопрос проверяет понимание AOP-прокси и причин, по которым аннотации могут «не срабатывать».
Self-invocation — это вызов метода бина из другого метода того же бина. Такой вызов происходит напрямую, минуя прокси Spring. В результате AOP-аннотации не применяются. Это часто приводит к тому, что @Transactional или @Async не работают. Проблема неочевидна и часто встречается на практике.
Self-invocation — следствие прокси-модели Spring.
Когда бин вызывает свой же метод:
вызов идет через this
прокси не участвует
AOP-логика пропускается
Это относится к:
@Transactional
@Async
@Cacheable
другим AOP-аннотациям
public void methodA() {
methodB(); // @Transactional на methodB не сработает
}
Spring:
оборачивает бин в прокси
перехватывает внешние вызовы
не перехватывает внутренние вызовы объекта
Это компромисс между простотой и производительностью.
Основные подходы:
вынести метод в отдельный бин
вызывать бин через интерфейс
использовать ApplicationContext (не рекомендуется)
применять AspectJ weaving
Self-invocation:
не баг Spring
а архитектурное ограничение
которое нужно учитывать при проектировании
Вывод: self-invocation ломает AOP-аннотации, потому что внутренние вызовы обходят прокси Spring.