此注释适用于Spring声明性事务吗
据我所知,Spring使用JDK为实现任何inferface的类生成动态代理,而使用Cglib为未实现任何inferface的类生成动态代理。对于decarative transaction,Spring使用代理添加事务方面。请看下面的代码:此注释适用于Spring声明性事务吗,spring,proxy,aop,transactional,cglib,Spring,Proxy,Aop,Transactional,Cglib,据我所知,Spring使用JDK为实现任何inferface的类生成动态代理,而使用Cglib为未实现任何inferface的类生成动态代理。对于decarative transaction,Spring使用代理添加事务方面。请看下面的代码: interface Demo { void methodA(); } public class DemoImpl implements Demo{ @Transactional public void updateA() {}
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" />
JDK动态代理
在这种情况下,您的bean被一个实现Demo
接口的代理包装起来。从那时起,您只能使用该接口。尝试注入或获取DemoImpl
类型的bean将导致可怕的错误
这种方法回答了您的问题-您只能访问updateA()
,这是唯一的事务性方法。忽略updateB()
周围的注释
但是,如果从updateA()
调用updateB()
,它将是事务性的,因为它将绑定到由updateA()
启动的事务(使用默认事务传播)
CGLIB代理
在这种情况下,接口被忽略。将创建DemoImpl
的子类(显然也实现了Demo
接口),并在两个update*()
方法上应用事务行为。现在,如果您注入类型为DemoImpl
(在这种情况下根本不需要接口,Impl
后缀很难看)的bean,您可以安全地事务性地调用这两个方法
有关更多详细信息,请参阅我的文章:和。JDK动态代理
在这种情况下,您的bean被一个实现Demo
接口的代理包装起来。从那时起,您只能使用该接口。尝试注入或获取DemoImpl
类型的bean将导致可怕的错误
这种方法回答了您的问题-您只能访问updateA()
,这是唯一的事务性方法。忽略updateB()
周围的注释
但是,如果从updateA()
调用updateB()
,它将是事务性的,因为它将绑定到由updateA()
启动的事务(使用默认事务传播)
CGLIB代理
在这种情况下,接口被忽略。将创建DemoImpl
的子类(显然也实现了Demo
接口),并在两个update*()
方法上应用事务行为。现在,如果您注入类型为DemoImpl
(在这种情况下根本不需要接口,Impl
后缀很难看)的bean,您可以安全地事务性地调用这两个方法
请参阅我的文章:更多详细信息。谢谢你,托马斯兹。如果我有以下配置,Spring会为我选择哪种情况:@Jacky:默认情况下Spring使用JDK代理。如果设置了
代理目标类
属性,它将升级为CGLIB代理,请参阅:。谢谢,Tomasz。如果我有以下配置,Spring会为我选择哪种情况:@Jacky:默认情况下Spring使用JDK代理。如果设置了代理目标类
属性,它将升级为CGLIB代理,请参阅:。