什么是基于接口的代理?

时间:2017-08-02 14:33:40

标签: java spring proxy spring-jdbc transactional

我正在读这个关于在哪里放置Transactional(接口与实现):

  

Spring团队的建议是,您只使用@Transactional注释来注释具体类,而不是注释接口。您当然可以将@Transactional注释放在接口(或接口方法)上,但是这只会在您使用基于接口的代理时按预期工作。注释的事实是不继承意味着如果您使用基于类的代理,那么基于类的代理基础结构将无法识别事务设置,并且该对象将不会被包装在事务代理中(这将是非常糟糕的)。因此,请参考Spring团队的建议,并使用@Transactional注释仅注释具体类(以及具体类的方法)。

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

1 个答案:

答案 0 :(得分:3)

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

  

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

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

  

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

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

  

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

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

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