动态代理的事务封装
? ? ? ? ?在上篇博客中介紹了使用ThreadLocal維護Connection的方法,這樣做的最大的優點就是不用來回的傳遞Connection了,可是我們有會發如今我們使用事務的時候不可避免的會寫很多反復的代碼,這些都是與業務邏輯無關的: ? ? ? ? ?
Connection conn = ConnectionManage.GetConnection();ConnectionManage.beginTransaction(conn); ConnectionManage.commitTransaction(conn);//等等代碼。
//以及Catch中的事務回滾,和finally中關閉連接等等
? ? ? ? 不僅不合理。并且是反復勞動,程序開發的一個原則就是杜絕反復勞動。做到良好的封裝。
? ? ? ? 這里,我們就採用動態代理對事務進行封裝,使我們的業務邏輯層不再出現有關事務的代碼。
package com.hanyi.drp.util;import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection;/*** 使用動態代理封裝事務* @author hanyi**/ public class TransactionHandler implements InvocationHandler {private Object targetObject;/*** 獲取目標類的代理* @param targetObject* @return*/public Object newProxyInstance(Object targetObject) {this.targetObject = targetObject;return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(), this);}/*** 代理方法。調用目標類方法前先調用該方法*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Connection conn = null;Object ret = null;try {// 從ThreadLocal中取得Connection。ConnectionManage是對connection的封裝conn = ConnectionManage.GetConnection();//假設是以add,del,modify開頭的方法,則手動開啟事務if (method.getName().startsWith("add")|| method.getName().startsWith("del")|| method.getName().startsWith("modify")) {// 手動控制事務提交ConnectionManage.beginTransaction(conn);}// 調用目標對象的業務邏輯方法ret = method.invoke(targetObject, args);//假設事務為手動提交方式,則手動提交事務if (!conn.getAutoCommit()) {// 提交事務ConnectionManage.commitTransaction(conn);}} catch (Exception e) {//假設事務為手動提交方式。則手動回滾事務if (!conn.getAutoCommit()) {// 回滾事務ConnectionManage.rollbackTransaction(conn);}e.printStackTrace();if (e instanceof InvocationTargetException) {InvocationTargetException ete = (InvocationTargetException) e;throw ete.getTargetException();}throw new Exception("操作失敗!");} finally {//關閉連接ConnectionManage.closeConnection();}return ret;}}原理:當我們在工廠中獲取業務邏輯層對象的時候,我們獲取的并非目標對象。而是目標對象的代理,代理替我們管理事務的開啟。提交。回滾,與關閉
?
在工廠中用動態代理包裝業務邏輯對象
public synchronized Object GetServiceBean(Class c) { if (ServiceMap.containsKey(c.getName())) { return ServiceMap.get(c.getName()); } Element beanEle = (Element) doc.selectSingleNode("//Service[@id=\"" + c.getName() + "\"]"); String className = beanEle.attributeValue("class"); // System.out.print(className); Object serviceBean = null; try { serviceBean = Class.forName(className).newInstance(); //採用動態代理包裝Service TransactionHandler transactionHandler = new TransactionHandler(); //得到代理 serviceBean = transactionHandler.newProxyInstance(serviceBean); ServiceMap.put(c.getName(), serviceBean); } catch (Exception e) { throw new RuntimeException(); } return serviceBean; } 在詳細的使用過程中,獲取的并非目標對象,而是目標對象的代理。userManager = (UserManager) getBeanFactory().GetServiceBean(UserManager.class);
版權聲明:本文博客原創文章,博客,未經同意,不得轉載。
總結
 
                            
                        - 上一篇: 多图上传 - Web Uploader
- 下一篇: 转盘不转动的问题
