1

据我所知,Spring使用JDK为实现任何接口的类生成动态代理,而使用Cglib为不实现任何接口的类生成动态代理。对于描述性事务,Spring 使用代理来添加事务方面。请看下面的代码:

interface Demo {
    void methodA();
}
public class DemoImpl implements Demo{
    @Transactional
    public void updateA() {}
    @Transactional
    public void updateB() {}
}

我认为 updateA 可以很好地处理事务。但是 updateB 方法呢?@Transactional 对它有用吗?可能我的理解不正确。如果能提供相关的Spring源码解释Spring是如何使用JDK/cglib代理类和接口的就好了。谢谢

我在xml中有配置:

<tx:annotation-driven transaction-manager="transactionManager" /> 
4

1 回答 1

1

JDK动态代理

在这种情况下,您的 bean 被一个代理实现Demo接口包装。从那一刻起,您只能使用该界面。尝试注入或获取DemoImpl类型的 bean 将导致可怕的抽象 DAO 模式和 Spring 的“代理无法强制转换为 ...”问题!

这种回答你的问题 - 你只能访问updateA(),这是唯一的交易方法。周围的注释updateB()被忽略。

但是,如果您updateB()从中调用updateA()它将是事务性的,因为它将绑定到由updateA()(使用默认事务传播)启动的事务。

CGLIB 代理

在这种情况下,接口被忽略。将创建一个子类DemoImpl(显然也是实现接口)并在这两个方法Demo上应用事务行为。update*()现在,如果您注入 bean 类型DemoImpl(在这种情况下根本不需要接口并且Impl后缀很丑陋),您可以安全地以事务方式调用这两种方法。

有关详细信息,请参阅我的文章:Spring 陷阱:代理Spring AOP 之谜

于 2012-05-13T08:33:37.097 回答