【问题标题】:Spring recommendations: proxying mechanism vs @Transactional on class or interfaceSpring 建议:类或接口上的代理机制 vs @Transactional
【发布时间】:2025-12-10 16:05:02
【问题描述】:

Spring doc 有两个建议:

Spring 建议您只注释具体的类(和方法 具体类)与@Transactional 注释,而不是 注释接口。你当然可以把@Transactional 接口(或接口方法)上的注释,但这有效 仅当您使用基于界面的 代理。 Java注解不是继承自的事实 接口意味着如果您使用基于类的代理 (proxy-target-class="true") 或基于编织的方面 (mode="aspectj"),则交易设置不被识别 代理和编织基础设施,并且对象不会 包裹在事务代理中,这绝对是糟糕的。

(来自http://static.springsource.org/spring/docs/3.0.x/reference/transaction.html

Spring AOP 使用 JDK 动态代理或 CGLIB 来创建 给定目标对象的代理。 (JDK 动态代理是首选 随时选择)。

(来自http://static.springsource.org/spring/docs/3.0.x/reference/aop.html#aop-understanding-aop-proxies

我是否理解正确,为了遵循这两个建议,我需要在具体类上有@Transactional 注释,但仍然提供一个包含所有事务方法的接口(该类实现),以便 Spring 可以使用 JDK dynamix这个接口的代理?

【问题讨论】:

  • 是的,你的理解是正确的。
  • 顺便说一句:我建议使用 Compile Time AspectJ,然后即使您从同一个 bean (this.otherMethod()) 中调用方法,也会考虑 Aspect。

标签: java spring transactions aop spring-aop


【解决方案1】:

它是这样工作的

  1. 有带方法的业务接口,不要用@Transactional注解接口方法

  2. 为上面定义的接口写一个实现类,并用@Transactional注解impl类中的方法

由于 Spring 建议使用基于接口的 JDK 动态代理,因此我们需要准备好业务接口。 另外,如前所述

Java 注释不是从接口继承的

我们需要用@Transactional注解具体/实现类方法

【讨论】: