什么是基于接口的代理? [英] What is interface-based proxying?

查看:92
本文介绍了什么是基于接口的代理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读有关在哪里放置事务(接口与实现)的内容:

I was reading this regarding to where to place Transactional(interface vs implementation):

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

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.

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

So the question is what is interface-based proxy exactly and how can I see if it is used? Is it some configuration or it is the way how I instantiate/use instances?

推荐答案

如果 Spring 无法创建 JDK 代理(或者如果您通过设置 proxyTargetClass 为真)然后代码不会在事务上下文中执行,因为(如 Spring 文档所述):

If Spring cannot create a JDK proxy (or if you force Spring to create a CGLIB proxy by setting proxyTargetClass to true) then the code will not execute in a transactional context because (as the Spring docs state):

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

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

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

So, I think your concerns are:

你怎么确定Spring没有创建CGLIB代理

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.

You must be configuring AOP based transactional support. If you are doing this by using <tx:annotation-driven/> then the default value for proxy-target-class (false) will suffice though could be explicit about this by setting: <tx:annotation-driven proxy-target-class="false"></tx:annotation-driven>. If you are configuring transactional support in some other way (using Java config, for example) then just ensure that the value of TransactionProxyFactoryBean.proxyTargetClass is false.

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

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

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

This is easy, just annotate the concrete class with the @Transactional annotation instead of annotating the interfaces. This avoids any issues with proxying.

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

In summary, Spring should use interface based proxying as long as TransactionProxyFactoryBean.proxyTargetClass is false however, if you annotate a concrete class rather than an implementation then the issue of proxying won't affect transactional support.

这篇关于什么是基于接口的代理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆