我问了这个问题,但它已关闭,我还没有得到确切的答案; 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:
现在有了这些信息,只有当通过具有此注释方法的类的代理对象调用该方法时,用 @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/