gpt4 book ai didi

java - 在 Java 8 默认接口(interface)方法上使用 Spring @Transactional 注释是否安全?

转载 作者:IT老高 更新时间:2023-10-28 13:55:05 25 4
gpt4 key购买 nike

Spring 文档建议不要将@Transactional 注解放在接口(interface)方法上,因为接口(interface)注解不会被类继承。但是,使用 Java 8,我们可以在接口(interface)中提供具体的默认实现。如果这样一个默认的接口(interface)方法需要作为事务边界,我们别无选择:必须在接口(interface)方法上加上@Transactional注解。

这会起作用吗(即在这种情况下,spring 会尊重事务边界)吗?如果是这样,这种方法是否有任何隐藏的陷阱?

最佳答案

在为使用 @Transactional 注释的类或包含使用 @Transactional 注释的方法生成代理 bean 时,Spring 使用(以及其他)BeanFactoryTransactionAttributeSourceAdvisor 作为 Advisor >.

当需要代理它时,它使用 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()

表示该注解是为接口(interface)的方法继承的。因此,当类没有覆盖 default 方法时,Spring 似乎能够添加 @Transactional 行为。如果它已覆盖它,则注释不会被继承。

关于java - 在 Java 8 默认接口(interface)方法上使用 Spring @Transactional 注释是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20460957/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com