什么是基于接口的代理?

What is interface-based proxying?

我正在阅读关于在哪里放置事务(接口与实现)的文章:

The Spring team's recommendation is that you only annotate concrete classes with the @Transactional annotation, as opposed to annotating interfaces. You certainly can place the @Transactional annotation on an interface (or an interface method), but this will only work as you would expect it to if you are using interface-based proxies. The fact that annotations are not inherited means that if you are using class-based proxies then the transaction settings will not be recognised by the class-based proxying infrastructure and the object will not be wrapped in a transactional proxy (which would be decidedly bad). So please do take the Spring team's advice and only annotate concrete classes (and the methods of concrete classes) with the @Transactional annotation.

所以问题是 interface-based proxy 到底是什么,我怎么知道它是否被使用了?是某种配置还是我 instantiate/use 个实例的方式?

如果 Spring 无法创建 JDK 代理(或者如果您通过将 proxyTargetClass 设置为 true 来强制 Spring 创建 CGLIB 代理)那么代码将不会在事务上下文中执行,因为(如 Spring 文档状态):

The fact that annotations are not inherited means that if you are using class-based proxies then the transaction settings will not be recognised by the class-based proxying infrastructure and the object will not be wrapped in a transactional proxy

所以,我认为您的顾虑是:

How can you be sure that Spring does not create a CGLIB proxy

您必须配置基于 AOP 的事务支持。如果您通过使用 <tx:annotation-driven/> 来执行此操作,那么 proxy-target-class (false) 的默认值就足够了,尽管可以通过设置 <tx:annotation-driven proxy-target-class=“false"></tx:annotation-driven> 明确说明这一点。如果您以其他方式配置事务支持(例如,使用 Java 配置),则只需确保 TransactionProxyFactoryBean.proxyTargetClass 的值为 false。

How can you be sure that your @Transactional annotations are respected

这很简单,只需用 @Transactional 注解来注解具体的 class 而不是注解接口。这避免了任何代理问题。

总而言之,只要 TransactionProxyFactoryBean.proxyTargetClass 为 false,Spring 就应该使用基于接口的代理,但是,如果您注释具体的 class 而不是实现,那么代理问题就解决了'影响交易支持。