要達到的目的是,很多表都繼承自了一個BizOrder的業務單基表,存放的是業務單的狀態,單號等數據。所以在保存一個庫存單的時候,就要
第一步:先保存BizOrder表
第二步:保存PioAccept表
在manager裏面要調用兩個不同的DAO來實現這個功能。目前是將第一個事情交給AOP的實現類來完成。平時coder在完成代碼時,只用
一步:保存PioAccept表
AOP的spring配置文件core-context.xml的片段如下:
<aop:config>
<!-- 配置功能實現類 -->
<aop:aspect ref="bizOrderAOP">
<!-- 攔截save名字打頭的方法,並傳遞參數Object obj -->
<aop:pointcut id="theExecutionOfBizOrderSaveMethod"
expression="execution(* cn.sccl..*.dao.*DAO.save*(Object)) and args(obj)" />
<!-- 攔截delete名字打頭的方法 -->
<aop:pointcut id="theExecutionOfBizOrderDeleteMethod"
expression="execution(* cn.sccl..*.dao.*DAO.delete*(..))" />
<!-- save的時候調用的實現類裏面的方法名 -->
<aop:around pointcut-ref="theExecutionOfBizOrderSaveMethod"
method="saveBizOrder" />
<!-- delete的時候調用的實現類裏面的方法名 -->
<aop:around pointcut-ref="theExecutionOfBizOrderDeleteMethod"
method="deleteBizOrder" />
</aop:aspect>
</aop:config>
我們的AOP操作實現類BizOrderAOPImpl.java:
package cn.sccl.base.aop;
import javax.annotation.Resource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Service;
import cn.sccl.base.dao.BizOrderDAO;
import cn.sccl.construction.model.PioAccept;
@Service("bizOrderAOP")
public class BizOrderAOPImpl {
<!-- 注入基類的DAO -->
private BizOrderDAO bizOrderDAO;
private static Log log = LogFactory.getLog(BizOrderAOPImpl.class);
@Resource(name = "bizOrderDAO")
public void setBizOrderDAO(BizOrderDAO bizOrderDAO) {
this.bizOrderDAO = bizOrderDAO;
}
<!-- 保存時調用的方法其中的Object是傳遞過來的方法參數,我這裏是PioAccept,實際用的時候需要instanceof吧。 -->
public Object saveBizOrder(ProceedingJoinPoint call,Object obj) throws Throwable {
<!-- 方法名,得到形如:execution(save) -->
log.debug("method name is : " + call.toShortString());
<!-- 得到參數 -->
log.debug("args is : " + obj);
PioAccept pio = (PioAccept)obj;
<!-- 斷點調試了,可以update參數 -->
pio.setBizOrderId(1111);
log.debug("ivoke method is : " + bizOrderDAO);
try {
return call.proceed();
} finally {
// if (true) {
// throw new RuntimeException("kill all!");
// }
}
}
public Object deleteBizOrder(ProceedingJoinPoint call) throws Throwable {
log.debug("method name is : " + call.toShortString());
log.debug("args is : " + call.getArgs()[0].toString());
log.debug("ivoke method is : " + bizOrderDAO);
try {
return call.proceed();
} finally {
// if (true) {
// throw new RuntimeException("kill all!");
// }
}
}
}
先在AOP中保存BizOrder表,然後保存自己的業務表,同時操作了兩個表,事務要保證,所以這個AOP配置在了DAO層。
正常情況的save方法日誌:
啓動事務
11-17 17:43:42 [DEBUG] org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371) - Creating new transaction with name [cn.sccl.common.service.BaseManager.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
11-17 17:43:47 [DEBUG] org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:202) - Acquired Connection [jdbc:oracle:thin:@10.206.20.5:1521:ccdev, UserName=DEV, Oracle JDBC driver] for JDBC transaction
11-17 17:43:47 [DEBUG] org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:219) - Switching JDBC Connection [jdbc:oracle:thin:@10.206.20.5:1521:ccdev, UserName=DEV, Oracle JDBC driver] to manual commit
調用AOP方法,得到如下參數
11-17 17:43:47 [DEBUG] cn.sccl.base.aop.BizOrderAOPImpl.saveBizOrder(BizOrderAOPImpl.java:25) - method name is : execution(save)
11-17 17:43:47 [DEBUG] cn.sccl.base.aop.BizOrderAOPImpl.saveBizOrder(BizOrderAOPImpl.java:26) - args is : cn.sccl.base.model.BizOrder@75c78d
11-17 17:43:47 [DEBUG] cn.sccl.base.aop.BizOrderAOPImpl.saveBizOrder(BizOrderAOPImpl.java:27) - ivoke method is : cn.sccl.base.dao.impl.BizOrderDAOImpl@800aa1
11-17 17:43:48 [DEBUG] cn.sccl.base.aop.BizOrderAOPImpl.saveBizOrder(BizOrderAOPImpl.java:25) - method name is : execution(save)
11-17 17:43:48 [DEBUG] cn.sccl.base.aop.BizOrderAOPImpl.saveBizOrder(BizOrderAOPImpl.java:26) - args is : cn.sccl.construction.model.PioAccept@b8d09d
11-17 17:43:48 [DEBUG] cn.sccl.base.aop.BizOrderAOPImpl.saveBizOrder(BizOrderAOPImpl.java:27) - ivoke method is : cn.sccl.base.dao.impl.BizOrderDAOImpl@800aa1
11-17 17:43:48 [DEBUG] org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:730) - Initiating transaction commit
提交事務
11-17 17:43:48 [DEBUG] org.springframework.jdbc.datasource.DataSourceTransactionManager.doCommit(DataSourceTransactionManager.java:259) - Committing JDBC transaction on Connection [jdbc:oracle:thin:@10.206.20.5:1521:ccdev, UserName=DEV, Oracle JDBC driver]
11-17 17:43:48 [DEBUG] org.springframework.jdbc.datasource.DataSourceTransactionManager.doCleanupAfterCompletion(DataSourceTransactionManager.java:314) - Releasing JDBC Connection [jdbc:oracle:thin:@10.206.20.5:1521:ccdev, UserName=DEV, Oracle JDBC driver] after transaction
模擬出錯時,拋出RuntimeException的日誌如下:
啓動事務
11-17 17:48:23 [DEBUG] org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371) - Creating new transaction with name [cn.sccl.common.service.BaseManager.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
11-17 17:48:26 [DEBUG] org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:202) - Acquired Connection [jdbc:oracle:thin:@10.206.20.5:1521:ccdev, UserName=DEV, Oracle JDBC driver] for JDBC transaction
11-17 17:48:26 [DEBUG] org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:219) - Switching JDBC Connection [jdbc:oracle:thin:@10.206.20.5:1521:ccdev, UserName=DEV, Oracle JDBC driver] to manual commit
調用AOP方法
11-17 17:48:26 [DEBUG] cn.sccl.base.aop.BizOrderAOPImpl.saveBizOrder(BizOrderAOPImpl.java:25) - method name is : execution(save)
11-17 17:48:26 [DEBUG] cn.sccl.base.aop.BizOrderAOPImpl.saveBizOrder(BizOrderAOPImpl.java:26) - args is : cn.sccl.base.model.BizOrder@41a12f
11-17 17:48:26 [DEBUG] cn.sccl.base.aop.BizOrderAOPImpl.saveBizOrder(BizOrderAOPImpl.java:27) - ivoke method is : cn.sccl.base.dao.impl.BizOrderDAOImpl@bd4e3c
11-17 17:48:27 [DEBUG] org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:821) - Initiating transaction rollback
AOP方法中有錯誤,回滾操作
11-17 17:48:27 [DEBUG] org.springframework.jdbc.datasource.DataSourceTransactionManager.doRollback(DataSourceTransactionManager.java:273) - Rolling back JDBC transaction on Connection [jdbc:oracle:thin:@10.206.20.5:1521:ccdev, UserName=DEV, Oracle JDBC driver]
11-17 17:48:27 [DEBUG] org.springframework.jdbc.datasource.DataSourceTransactionManager.doCleanupAfterCompletion(DataSourceTransactionManager.java:314) - Releasing JDBC Connection [jdbc:oracle:thin:@10.206.20.5:1521:ccdev, UserName=DEV, Oracle JDBC driver] after transaction