動的エージェント結合物事の応用

4140 ワード

jdk 1.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;
	}

}