設計模式的應用-動態代理實現事務控制

在WEB的三層架構的業務邏輯層中,每一個業務邏輯方法,要麼執行成功,提交事務;要麼執行失敗,回滾事務。數據庫

下面用代理的方式實現事務的控制:架構

動態事務代理

封裝了兩個工具類DBUtil, TranscationUtil, 前者用於當前線程的數據庫鏈接的獲取和關閉,後者控制當前線程數據庫鏈接事務的處理。ide

首先,新建動態代理類com.ploy.service.proxy.TranscationProxy類,並使用cglib實現動態代理:工具

/**
 * 數據庫事務代理類
 * 
 * @author 
 * 
 */
public class TranscationProxy {

       /**
        * 得到代理對象
        */
    public static <T> T getProxy(Class<T> clazz) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);

        // 設置回調方法
        enhancer.setCallback(new MethodInterceptor() {

            /*
             * 事務方法攔截
             * @param object 被代理的對象(service對象)
             * @param method 被調用的方法(原service的某個方)
             * @param args 被代理的方法的傳入參數
             * @param proxy 多出來的參數是MethodProxy 類型的,它應該是cglib生成用來代替Method對象的一個對象
             */
            @Override
            public Object intercept(Object object, Method method,
                    Object[] args, MethodProxy proxy) throws Throwable {
                Object result = null;
                    // 開啓一個全新的事務
                    TranscationUtil.begin();
                    try {
                        result = proxy.invokeSuper(object, args); // 反射執行原有serivce方法
                        // 執行成功,提交事務
                        TranscationUtil.commit();
                    } catch (Exception e) {
                        // 執行失敗回滾事務
                        TranscationUtil.rollback();
                        throw e;
                    }
            }

        });
        // 建立一個代理對象
        return (T) enhancer.create();
    }

}

而後看看Service工廠類,實際上生產的是具備代理功能的Serice對象:線程

/**
 * ServiceFactory類工廠
 * 
 * @author 
 *
 */
public class ServiceFactory {
    private static Map<Class<?>, Object> SERVICE_MAP = new HashMap<>();
    
    static {
        SERVICE_MAP.put(ManagerService.class, TranscationProxy.getProxy(ManagerServiceImpl.class));
        SERVICE_MAP.put(UserService.class, TranscationProxy.getProxy(UserServiceImpl.class));
    }
    
    
    public static<T> T getService(Class<T> clazz) {
        return (T) SERVICE_MAP.get(clazz);
    }
    
}

經過工廠類向控制層注入帶有事務功能的service對象。代理

相關文章
相關標籤/搜索