Почему в контроллерах или сервисах мы можем получить ленивый загруженный прокси-объект, но не в подклассе AbstractUserDetailsAuthenticationProvider? - PullRequest
0 голосов
/ 06 февраля 2020

Я задал этот вопрос, но он закрыт, и я точно не получил свой ответ; Spring @Transactional аннотация не работает в классе провайдера, который является подклассом AbstractUserDetailsAuthenticationProvider

И я прочитал этот ответ; Spring - @Transactional - Что происходит в фоновом режиме?

Они говорили что-то о внутреннем вызове метода и внешнем вызове метода. Но это работает в любом контроллере или сервисе. Почему не в классе провайдера, который аннотирован как @Component? Почему Spring или Hibernate не могут открыть сеанс в классе провайдера даже с аннотацией @Transactional? Это что-то о весенней безопасности? В чем разница?

1 Ответ

0 голосов
/ 08 февраля 2020

Пожалуйста go по ссылке Документация

На следующих изображениях показан концептуальный вид вызова метода на транзакционном прокси:

enter image description here

Теперь с этой информацией метод, отмеченный @Transactional, начнет транзакцию только тогда, когда вызов метода поступит через прокси-объект класса, который имеет этот аннотированный метод. Этот вызов упоминается экспертами в вашем предыдущем вопросе как внешний вызов .

В случае вашего примера

Реализация абстрактного метода AbstractUserDetailsAuthenticationProvider. retrieveUser () вызывается из AbstractUserDetailsAuthenticationProvider.authenticate () , который является самостоятельным вызовом. Это то, что эксперты называют внутренний звонок . Также обратите внимание, что метод authenticate() не является @Transactional

Go в документации по разделу Использование транзакций

В режиме прокси (который по умолчанию), только внешние вызовы методов, поступающие через прокси, перехватываются. Это означает, что самовывоз (по сути, метод в целевом объекте, вызывающий другой метод целевого объекта) не приводит к фактической транзакции во время выполнения, даже если вызванный метод помечен @Transactional. Кроме того, прокси-сервер должен быть полностью инициализирован, чтобы обеспечить ожидаемое поведение, поэтому вам не следует полагаться на эту функцию в коде инициализации (т. Е. @PostConstruct).

в аннотированном классе вашего провайдера с @Component вызов прокси достигает метода, который не аннотирован с помощью @Transactional, и выполняет собственный вызов или внутренний вызов метода с аннотацией @Transactional, который не работает, как объяснено ранее

Для контроллера или службы метод, отмеченный @Transactional, вызывается первым (внешний вызов), который инициирует транзакцию. Поток кода в контексте этого метода находится в транзакции, и все последующие методы участвуют в этой транзакции, и вы не видите исключение - no Session.

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...