在Spring中重写@Transactional注解的方法时的行为是什么

问题描述 投票:0回答:1

有关于 spring 注解“继承”的“重复”问题,答案很坚决,但可能不正确:否。

当然,当我们重写方法时,注释不会被继承。但仅仅

的存在
org.springframework.core.annotation.AnnotationUtils#findAnnotation 

遵循方法重写引出了一个问题:是否(以及如何)@Transactional 注释“继承”。我还可以找到:

org.springframework.core.annotation.MergedAnnotations.SearchStrategy

其中 TYPE_HIERARCHY 枚举特别表明 spring “继承”它们。

问题:

  1. 所以在父类方法中有

    @交易 公共无效a(){}

及其子类方法

@Overrides public void a() {}
如果我调用a(),是否会打开交易?让我们假设,代理已正确创建,方法是公共的,等等。其他一切都很好。

  1. 考虑到显然有多种策略,是否有一些文档/最佳实践如何配置此行为。

  2. 有谁知道这些规则记录在哪里,我想知道如果父级是接口或抽象方法等会发生什么,并且执行扫描的代码并不那么容易,不能确定我没有忽略某些东西.

java spring hibernate-annotations
1个回答
0
投票
检查

@Transactional

Javadoc:

当此注释在类级别

声明时,它将作为默认值应用于声明类及其子类的所有方法。请注意,它不适用于类层次结构中的祖先类; 继承的方法需要在本地重新声明才能参与子类级别的注释。有关方法可见性约束的详细信息,请参阅参考手册的事务管理部分。 所以,如果你有

@Transactional public class YourSuperClass {} @Component public class YourSubClass { public void someMethod(){ //whatever } }

那么
someMethod
在逻辑上就是

@Transactional

(从Spring的角度来看)。如果 
someMethod
 被覆盖,这也适用。
但是,情况不同

public class YourSuperClass { @Transactional public void someMethod(){ } } @Component public class YourSubClass extends YourSuperClass { @Override public void someMethod(){ //whatever } }

在这种情况下,
someMethod
将不会是事务性的,除非您明确注释覆盖的版本。

所以,对于你的问题:

那么在父类方法和子类方法中,如果我调用a(),是否会打开事务?让我们假设,代理已正确创建,方法是公共的,等等。其他一切都很好。
  1. 不。如前所述,重写的方法不会是事务性的。但是,您可以通过围绕该方法创建一个包装器来解决这个问题:
public class YourSuperClass { @Transactional public final void yourMethod(){ yourMethodImpl(); } protected void yourMethodImpl(){ //whatever } } @Component public class YourSubClass extends YourSuperClass{ @Override protected void yourMethodImpl(){ //whatever } }

那么如果调用
yourMethodImpl

yourMethod

 将在事务中执行。

考虑到显然有多种策略,是否有一些文档/最佳实践如何配置此行为。
  1. 如前所述,您可以检查
@Transactional

Javadoc,其中提到它是在类级别继承的,但在重写方法时则不是。我不知道还有什么其他策略。



有谁知道这些规则记录在哪里,我想知道如果父级是接口或抽象方法等会发生什么,并且执行扫描的代码并不那么容易,不能确定我没有忽略某些东西。
  1. 这些事情应该做同样的事情,但如果你想确定的话,我建议你自己尝试一下。

© www.soinside.com 2019 - 2024. All rights reserved.