读书人

采取动态代理对事务进行封装

发布时间: 2013-03-13 10:56:58 作者: rapoo

采用动态代理对事务进行封装

如果采用三层架构的方式开发,在业务逻辑层不可避免的要手动操作事务,所以在业务逻辑层会出现很多与业务逻辑无关的:

Connection conn = ConnectionManage.GetConnection();
ConnectionManage.beginTransaction(conn); ConnectionManage.commitTransaction(conn);等等代码。

不仅不合理,而且是重复劳动,程序开发的一个原则就是杜绝重复劳动,做到良好的封装。

这里,我们就采用动态代理对事务进行封装,使我们的业务逻辑层不再出现有关事务的代码。

package com.jialin.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 jialin * */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();//采用动态代理包装ServiceTransactionHandler 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);


读书人网 >编程

热点推荐