Spring文档建议不要将@Transactional注释放在接口方法上,因为接口注释不能被类继承。但是,对于Java 8,我们可以在界面中提供具体的默认实现。如果这种默认的接口方法需要作为事务边界,我们别无选择:我们必须在接口方法上放置@Transactional注解。在Java 8默认接口方法上使用Spring @Transactional注释安全吗?
这项工作(即在这种情况下是否会尊重事务边界)?如果是这样,这种方法有没有隐藏的陷阱?
Spring文档建议不要将@Transactional注释放在接口方法上,因为接口注释不能被类继承。但是,对于Java 8,我们可以在界面中提供具体的默认实现。如果这种默认的接口方法需要作为事务边界,我们别无选择:我们必须在接口方法上放置@Transactional注解。在Java 8默认接口方法上使用Spring @Transactional注释安全吗?
这项工作(即在这种情况下是否会尊重事务边界)?如果是这样,这种方法有没有隐藏的陷阱?
当生成代理Bean时,Spring使用(其中包括)一个BeanFactoryTransactionAttributeSourceAdvisor
作为Advisor
,该代理bean用于注释或包含用@Transactional
注释的方法。
当需要代理它时,它使用bean的类类型(使用CGLIB)来生成代理。所以我们想看看用@Transactional
注解的default
方法是否可以从实现类的角度看到。
这里是一个Java 8 SSCCE
public static void main(String[] args) throws Exception{
Class<?> randomImplClass = RandomImpl.class;
System.out.println(randomImplClass);
Easy annotation = randomImplClass.getAnnotation(Easy.class);
System.out.println("Class: " + randomImplClass);
System.out.println("Class Annotation: " + annotation);
Method method = randomImplClass.getMethod("doRandom");
annotation = method.getAnnotation(Easy.class);
System.out.println("Method: " + method);
System.out.println("Method Annotation: " + annotation);
}
public static class RandomImpl implements Random{}
@Easy
interface Random {
@Easy
default void doRandom() {System.out.println("testing");};
}
@Target(value = {METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Easy {}
它打印
class TestEnhancer$RandomImpl
Class: class TestEnhancer$RandomImpl
Class Annotation: null
Method: public default void TestEnhancer$Random.doRandom()
Method Annotation: @TestEnhancer$Easy()
表明注释被继承的接口的方法。因此,当类没有覆盖default
方法时,Spring似乎能够添加@Transactional
行为。如果它覆盖了它,则注释不会被继承。
非常好的测试。更进一步,您可以重写RandomImpl中的默认实现,并证明您必须将注释放在覆盖方法上才能看到它。我不认为这与使用继承有什么不同。 – JMB
@JMB对,我在本地做过,但没有在这里发布示例。最后一句覆盖了它。稍后回家时我会添加它。 –
如果您需要方法的默认实现,为什么不创建抽象类而不是接口? Java 8 API文档使我相信,接口默认方法主要是为了允许在接口中添加新方法而不破坏该接口的旧版本实现。 – VGR
接口默认方法允许您创建[mixins](https://en.wikipedia.org/wiki/Mixin),这是一个比传统的java接口更强大的编程结构。是否有合理的理由在事务中使用混合服务接口是另一个问题,但这不是不可想象的。使用抽象类也是可行的,但将您限制为线性对象层次结构。 Mixins更灵活。 – JMB