什么是基于接口的代理?

mel*_*onT 5 java proxy spring transactional spring-jdbc

我正在阅读有关在何处放置Transactional(接口与实现)的信息:

Spring团队的建议是您仅使用@Transactional注释对具体的类进行注释,而不是对接口进行注释。您当然可以在接口(或接口方法)上放置@Transactional批注,但这仅在您使用基于接口的代理时才可以按预期使用。注解未继承的事实意味着,如果您使用的是基于类的代理,则基于类的代理基础结构将无法识别事务设置,并且该对象也不会包装在事务性代理中(这肯定是不好的) 。因此,请听取Spring团队的建议,仅使用@Transactional批注对具体类(以及具体类的方法)进行批注。

所以问题是,到底什么是基于接口的代理,如何查看它是否被使用?是一些配置还是实例化/使用实例的方式?

gly*_*ing 4

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

\n\n
\n

注释不是继承的事实意味着,如果您使用基于类的代理,那么基于类的代理基础结构将无法识别事务设置,并且对象将不会包装在事务代理中

\n
\n\n

所以,我认为您的担忧是:

\n\n
\n

如何确定 Spring 不会创建 CGLIB 代理

\n
\n\n

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

\n\n
\n

如何确保您的 @Transactional 注释得到尊重

\n
\n\n

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

\n\n

总之,Spring 应该使用基于接口的代理,只要TransactionProxyFactoryBean.proxyTargetClassfalse,Spring 就应该使用基于接口的代理,但是,如果您注释具体类而不是实现,则代理问题不会影响事务支持。

\n

  • 还要添加以下答案:如果类是最终的,则 spring 无法创建代理或为一个类创建一些代理 (2认同)