动态代理结合事物的应用
在jdk1.3中或更高版本中继承java.lang.reflect.InvocationHandler实现动态代理
package com.read.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.sql.Connection;import com.read.util.ConnectionFactory;/** * 动态代理处理类 * @author * */public class TransactionWrapper {/** * 装饰原始的业务代表对象,返回一个与业务代表对象有相同接口的代理对象 */public static Object decorate(Object delegate) {return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),delegate.getClass().getInterfaces(), new XAWrapperHandler(delegate));}// 动态代理技术static final class XAWrapperHandler implements InvocationHandler {private final Object delegate;XAWrapperHandler(Object delegate) {this.delegate = delegate;}public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Connection conn = null;Object retValue = null;try {conn = JdbcQueryManager.getConnection();/** 如果方法名以‘add’,'delete','update'开头就启用事物 */if (method.getName().startsWith("add")|| method.getName().startsWith("delete")|| method.getName().startsWith("update")) {delegate.getClass().getMethod("setConn",Class.forName(Connection.class.getName())).invoke(delegate, new Object[]{conn});conn.setAutoCommit(false);System.out.println("开始事物.......");}else if(method.getName().startsWith("find")){//不启用事物conn.setAutoCommit(true);}else{//不启用事物conn.setAutoCommit(true);}// 调用目标对象上的业务逻辑方法retValue = method.invoke(delegate, args);if(!conn.getAutoCommit()){// 提交事务conn.commit();System.out.println("提交事物........");}} catch (Exception e) {e.printStackTrace();if(!conn.getAutoCommit()){conn.rollback();System.out.println("出错了,回滚数据........");}throw new Exception("操作错误!");} finally {//将连接放入连接池中ConnectionFactory.closeConnection(conn);}return retValue;}}}
package com.read.proxy;import java.sql.Connection;import com.read.util.StrUtil;/** * 测试,该类必须实现@see : com.read.proxy.TestProxyInter * @author 陈彪 * */public class TestProxy implements TestProxyInter {private ExecuteSQL exe = new ExecuteSQL();private Connection conn;public void setConn(Connection conn) {this.conn = conn;}public void addMat() throws Exception {try {exe.setConn(conn);exe.executeSql("insert into test(a) values(?)",new Object[]{StrUtil.replaceSql("1")});exe.executeSql("insert into test(a) values(?)",new Object[]{StrUtil.replaceSql("2")});exe.executeSql("insert into test(a) values(?)",new Object[]{StrUtil.replaceSql("3")});exe.executeSql("insert into test(a) values(?)",new Object[]{StrUtil.replaceSql("4")});//错误写法exe.executeSql("insert into test(af) values(?)",new Object[]{StrUtil.replaceSql("5")});} catch (Exception e) {e.printStackTrace();throw e;}}public static void main(String []args){TransactionWrapper in = new TransactionWrapper();TestProxyInter s = (TestProxyInter)in.decorate(new TestProxy());try {s.addMat();} catch (Exception e) {e.printStackTrace();}}public Connection getConn() {return conn;}}