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

标签 java spring transactions annotations java-8

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/

相关文章:

java - spring 上下文初始化时出现 IncompleteClassChangeError 错误

javascript - 为什么 mongoose abortTransaction() 不工作?

java - 使用 Terracotta 作为持久化解决方案

java - Mac 和 Windows 上的字节码

java - JSP 输出在 tomcat 8.0.17 中被截断

java - 在 Android Studio 中构建 APK 文件时出错

java - 重新部署后无效的 Jboss 数据源

java - 在使用 DLL 之前是否需要启用 Java Access 桥?

java - 如何在没有 Spring XML 上下文文件的情况下 Autowiring 对象?

spring - SpringBoot 1.5.* 上的执行器日志文件不起作用。 HTTP 404