java - 为什么在 Controller 或服务中,我们可以访问延迟加载的代理对象,但不能在 AbstractUserDetailsAuthenticationProvider 的子类中访问?

标签 java hibernate spring-boot spring-transactions

我问了这个问题,但它已关闭,我还没有得到确切的答案; Spring @Transactional annotation is not working in the provider class which is a subclass of AbstractUserDetailsAuthenticationProvider

我读了这个答案; Spring - @Transactional - What happens in background?

他们说了一些关于内部方法调用和外部方法调用的事情。但这适用于任何 Controller 或服务。为什么不在提供者类中注释为@Component?为什么即使使用 @Transactional 注解,Spring 或 Hibernate 也无法在提供程序类中打开 session ?这是关于 Spring 安全的事情吗?有什么区别?

最佳答案

请仔细阅读引用documentation

The following images shows a Conceptual view of calling a method on a transactional proxy:

enter image description here

现在有了这些信息,只有当通过具有此注释方法的类的代理对象调用该方法时,用 @Transactional 注解的方法才会启动事务。您在上一个问题中专家将此次通话称为外部通话

就您的示例而言,

抽象方法的实现AbstractUserDetailsAuthenticationProvider.retrieveUser()AbstractUserDetailsAuthenticationProvider.authenticate() 调用,这是一个自调用。这就是专家所说的内部调用。另请注意,方法 authenticate() 不是 @Transactional

浏览 Using Transactional 部分下的文档

In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation (in effect, a method within the target object calling another method of the target object) does not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional. Also, the proxy must be fully initialized to provide the expected behavior, so you should not rely on this feature in your initialization code (that is, @PostConstruct).

在使用 @Component 注解的提供程序类中,对代理的调用会到达未使用 @Transactional 注解的方法,并执行自调用或内部调用调用用 @Transactional 注释的方法,该方法不像之前解释的那样工作

对于 Controller 或 Service,首先调用使用 @Transactional 注释的方法(外部调用),从而启动事务。该方法上下文中的代码流位于事务中,并且所有后续方法都参与该事务,并且您不会看到 - no Session 异常。

希望这有帮助

关于java - 为什么在 Controller 或服务中,我们可以访问延迟加载的代理对象,但不能在 AbstractUserDetailsAuthenticationProvider 的子类中访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60089488/

相关文章:

java - 重新部署后,Alfresco VersionHistory 返回不同的错误版本

spring - Spring Data (Spring Boot) 和 Joda Time 字段映射的问题

Java 解析输出的消息

java - 为什么屏幕不变色

java - hibernate 流损坏异常

oracle - 带时区的 hibernate 时间戳

java - 设置 Spring Boot 应用程序以根据 session 的环境参数连接到不同的数据源

java - 如何使用/导入 @EnableRedisHttpSession Spring 注释?

spring - 使用保管库保护 Spring Cloud 配置凭据

java - 每个不同的 SQL 查询是否需要不同的 PreparedStatement 对象?