Part1精講設計模式_1.7代理模式_1.7.2純手寫Spring事務處理

                                         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);
    }
    
}

轉載請註明原作者
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章