spring提供的事务打点
spring提供的事务打点可以分为两类:编程式的和声明式的。编程式的,较量机动,可是代码量大, 存在反复的代码较量多;声明式的比编程式的更机动。编程式主要利用transactionTemplate。省略了部 分的提交,回滚,一系列的事务工具界说,需注入事务打点工具;声明式:主要利用 TransactionProxyFactoryBean,环绕Poxy的动态署理,可以或许自动的提交和回滚事务。统观spring事务, 环绕着两个焦点PlatformTransactionManager和TransactionStatus,下面我们以声明式方法来讲授。
Spring声明式是以署理的方法实现对事务的打点。我们在Action中所利用的Service工具,其实是署理 工具的实例,并不是我们所写的Service工具实例。既然是两个差异的工具,那为什么我们在Action中可 以象利用Service工具一样的利用署理工具呢?为了说明问题,假设有个Service类叫AService,它的 Spring事务署理类为AProxyService,AService实现了一个接口 IAService (这里多了一个接口 IAService,是为了说明接口署理的方法)。
Spring事务署理方法有两种,一种是类署理方法,一种 是接口署理方法。在Spring的设置文件中可以指定署理方法,今朝我们利用的都是类署理方法。 //以下 设置指定为类署理方法
<property name="proxyTargetClass"><value>true</value></property>
1、 类署理方法
类署理方法的实现方法是通过担任的方法来实现,下面用伪代码来说明。
interface IAService{ public void save(ValueObject object); } class AService implements IAService{ public void save(ValueObject object){ ... } } // Spring自动生成的署理类. class AProxyService extends AService{ public void save(ValueObject object){ try{ 启动事务的代码; super.save(object); 提交事务的代码; }catch(Exception e){ 回滚事务的代码; } } }
在Action的挪用代码:
AService a = (AService)getBean("aProxyServiceBeanName");
这里 getBean("aProxyServiceBeanName") 获得的是 AProxyService 类的实例,因为 AProxyService是AService的一个子类,所以这里可以强制转型为AService。我们后头挪用a.save (object)的时候,挪用的是AProxyService.save()要领,而这个要领是有事务处理惩罚的。Spring就是这样实 现了事务打点。 // 下面的这行代码也是同样的结果。
IAService a = (IAService)getBean ("aProxyServiceBeanName");
Spring通过CGLib来实现了类署理方法。
2、接口署理方法
接口署理方法是通过实现接口,引用类实例来实现的,所以这里必然要有一个接口 IAService,而类署理方法是不需要这个接口的。
// Spring自动生成的署理类. class AProxyService implements IAService{ private AService aService; public void setAService(AService aService){ this.aService = aService; } public void save(ValueObject object){ try{ 启动事务的代码; aService.save(object); // 留意这行代码与上面的差异。 提交事务的代码; }catch(Exception e){ 回滚事务的代码; } } }
在Action的挪用代码:
AService a = (AService)getBean("aProxyServiceBeanName");
上面这行代码会报ClassCastException错误,因为 getBean("aProxyServiceBeanName") 获得的是 AProxyService 类的实例,而AProxyService实例并不能转型为AService范例,固然两者都实现 了同一个接口,但他们之间并没有担任干系。就象ArrayList 和 LinkedList,他们可以转换成List,但 他们之间并不能相互转换。所以这里必需这样利用:
IAService a = (IAService)getBean ("aProxyServiceBeanName"); // 要转换成接口范例。
挪用a.save() 要领其实就是挪用 AProxyService.save() 要领。
Spring通过Java动态署理来实现接口署理
查察本栏目