【问题标题】:What is interface-based proxying?什么是基于接口的代理?
【发布时间】:2018-01-09 20:26:09
【问题描述】:

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

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

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

【问题讨论】:

    标签: java spring proxy spring-jdbc transactional


    【解决方案1】:

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

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

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

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

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

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

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

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

    【讨论】:

    • 如果类是最终类或为一个类创建一些代理,则弹簧无法创建代理的答案也添加了
    猜你喜欢
    • 2011-08-14
    • 1970-01-01
    • 2015-04-25
    • 2011-05-23
    • 2011-06-06
    • 2017-05-05
    • 1970-01-01
    • 1970-01-01
    • 2013-06-05
    相关资源
    最近更新 更多