Part 1 精講設計模式
1.7 代理模式
1.7.2 純手寫Spring事務處理
田超凡
2019-10-29
轉載請註明原作者
1.基於原生JDK動態代理和自定義事務處理器進行事務處理
代理目標:OrderService接口和OrderServiceImpl接口實現
package com.tcf.design.proxy.prototype.aop.target.service;
/***
* TODO TCF 訂單業務接口,代理目標
* @author Hasee
*
*/
public interface OrderService {
//TODO TCF 下單,代理目標方法
public void order();
}
package com.tcf.design.proxy.prototype.aop.target.service.impl;
import org.springframework.stereotype.Service;
import com.tcf.design.proxy.prototype.aop.target.service.OrderService;
/***
* TODO TCF 訂單業務接口實現類
* @author Hasee
*
*/
@Service("orderServiceImpl")
public class OrderServiceImpl implements OrderService {
@Override
public void order()
{
System.out.println("代理目標方法執行......");
}
}
JDK動態代理處理器 MyInvocationHandle
package com.tcf.design.proxy.prototype.aop.core;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.springframework.transaction.TransactionStatus;
import com.tcf.design.proxy.prototype.aop.util.SpringUtils;
/***
* TODO TCF JDK動態代理核心處理器-InvocationHandle
* @author Hasee
*
*/
public class MyInvocationHandle implements InvocationHandler {
//TODO TCF 代理目標實例
private Object target;
//TODO TCF 自定義事務管理器
private MyTransactionManager transactionManager;
//TODO TCF 構造柱入
public MyInvocationHandle(Object target)
{
this.target=target;
this.transactionManager=SpringUtils.getBean("myTransactionManager",MyTransactionManager.class);
}
//TODO TCF 代理實例需要執行的代理方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
Object invokeResult=null;
TransactionStatus status=null;
try
{
//TODO TCF 開啓事務處理
status=transactionManager.begin();
//TODO TCF 調用代理目標方法
invokeResult=method.invoke(target,args);
//TODO TCF 事務提交
transactionManager.commit(status);
}
catch(Exception e)
{
e.printStackTrace();
//TODO TCF 事務回滾
if(status!=null)
{
transactionManager.rollBack(status);
}
}
return invokeResult;
}
//TODO TCF 創建JDK動態代理實例
@SuppressWarnings("unchecked")
public <T> T getProxy()
{
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);
}
}
自定義事務管理器
package com.tcf.design.proxy.prototype.aop.core;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
/***
* TODO TCF 事務管理器,封裝事務處理操作
* @author Hasee
*
*/
@Component
public class MyTransactionManager {
//TODO TCF Spring AOP事務管理器
@Autowired
private DataSourceTransactionManager dataSourceTransactionManager;
//TODO TCF 開啓事務
public TransactionStatus begin()
{
TransactionStatus status=null;
if(dataSourceTransactionManager!=null)
{
status=dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
}
return status;
}
//TODO TCF 事務提交
public void commit(TransactionStatus status)
{
if(dataSourceTransactionManager!=null)
{
dataSourceTransactionManager.commit(status);
}
}
//TODO TCF 事務回滾
public void rollBack(TransactionStatus status)
{
if(dataSourceTransactionManager!=null)
{
dataSourceTransactionManager.rollback(status);
}
}
}
2.基於Spring AOP AspectJ註解實現事務處理
AOP切面類
package com.tcf.design.proxy.prototype.aop.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import com.tcf.design.proxy.prototype.aop.core.MyTransactionManager;
/***
* TODO TCF 事務管理器-切面
* @author Hasee
*
*/
@Aspect
@Component
public class TransactionAspect {
//TODO TCF 事務管理器
@Autowired
private MyTransactionManager transactionManager;
//TODO TCF 切入點
@Pointcut("execution(* com.tcf.design.proxy.prototype.aop.target.service..*.order(..))")
public void order()
{
}
//TODO TCF 異常拋出增強,拋出異常回滾事務
@AfterThrowing(pointcut="order()")
public void afterThrowing()
{
//TODO TCF 當前事務回滾
System.out.println("當前事務回滾......");
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
//TODO TCF 環繞增強,目標方法全部加入事務處理
@Around("execution(* com.tcf.design.proxy.prototype.aop.target.service..*.*(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable
{
//TODO TCF 開啓事務
TransactionStatus status=transactionManager.begin();
//TODO TCF 目標方法執行
proceedingJoinPoint.proceed();
//TODO TCF 事務提交
transactionManager.commit(status);
}
}
轉載請註明原作者