Spring Aop应用一例

起因:

做的项目,三层架构:domain层(dao)、façade层(business)、view层。View层用Extjs实现,使用SSH组合,在façade层配置了REQUIRED型事务,在domain层没有采用默认事务。按说,在façade层配置了事务之后,同一次操作(同一个façade方法)对domain层的调用一定应该是同一事务,这个由spring保证的。但领导怀疑看到有不一致的数据,怀疑是由于同一次操作没有在同一事务中(应该是系统开发过程中不完善造成的),让验证一下同一次façade层的操作,对domain层是不是在同一个事务中。

验证方法有两种:

1.  在一次façade层的方法入口处获取事务,保存,然后在调用相关的domain层方法中手动添加获取事务,验证和入口处的事务是不是同一事务。这种方案需要先在各相关方法中添加代码,验证完成后,再把新加的代码清除,工作量大,而且易出错。

2.  通过spring的aop功能,生成切面,在每个facade方法调用的domain方法前或后得到事务,验证同一次操作对domain层的方法是否在同一事务中。

鉴于第二种方法只需要独立生成一个新切面类,并修改配置方法就可以完成,而且可以借此机会学习一下spring的aop,所以决定采用第二种方案。

首先实现一个切面类:

public class MyAspect {
	public void doAfter(JoinPoint jp){
		System.out.println("log Ending method: "  
                + jp.getTarget().getClass().getName() + "."  
                + jp.getSignature().getName());  
	}
	public void doBefore(JoinPoint jp) {
		System.out.println("log Begining method: "  
                + jp.getTarget().getClass().getName() + "."  
                + jp.getSignature().getName());  }
}

然后修改spring配置文件beans.xml,添加如下内容:

	<!--切面实现1 Begin -->
	<aop:config>
		<aop:pointcut id="myAspectAA" expression="execution(* com.dfsoft.hummer.domain..*Impl.add*(..)) or execution(* com.dfsoft.hummer.domain..*Impl.del*(..)) or execution(* com.dfsoft.hummer.domain..*Impl.save*(..))"/>
		<aop:aspect id="myAspect" ref="myAspect1">
			<aop:before pointcut-ref="myAspectAA" method="doBefore"/>
			<aop:after pointcut-ref="myAspectAA" method="doAfter"/>
		</aop:aspect>
	</aop:config>
	<bean id="myAspect1" class="com.dfsoft.hummer.domain.common.MyAspect" /> 
	<!-- 切面实现1 End-->

运行程序,进行相关操作,查看结果,看到切面成功执行。

 

验证同一façade方法对domain的调用是否在同一事务,只需要使用before或after一个就行,我这里使用了before。修改before方法如下:

	public void doBefore(JoinPoint jp) {
		System.out.println();
		try{
			Method m = jp.getTarget().getClass().getDeclaredMethod("getSession"); //反射
			m.setAccessible(true); //使私有方法可操作
			Session s = (Session)m.invoke(jp.getTarget());			
			System.out.println(s.getTransaction().hashCode());
		}catch(Exception e){
			System.out.println("No such method: " + e.getMessage());
		}
		System.out.println("log Begining method: "  
                + jp.getTarget().getClass().getName() + "."  
                + jp.getSignature().getName());  
	}

再一次运行程序,进行相关操作,查看控制台,看到同一次操作输入的事务的hashcode是同一个,这就可以认为同一次façade方法调用,所有的domain调用是在同一事务中。

验证完成后,删除MyAspect类,清除配置文件中修改,就完成了还原的工作。

 

本来一个功能是应该写测试来保证后续的修改不会引入错误,但考虑到这个工作是一次性的,用完就清除了,所以就没有写测试。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值