[セットトップ]動的エージェントによる横断処理-トランザクションのカプセル化


前回の授業では,現象2により,それぞれに対して同じ制御を実現すると,大量のコードを繰り返し書く必要があることが分かった.たとえば、ログの書き込み、トランザクションのオン、オフ、ロールバックなどの一連の操作があります.
    しかし、開発の過程で、以上の開発に常に注意すれば、開発効率は低くなります.しかも間違いやすい.
    上記の問題に直面して、オブジェクト向けのプログラミングだけであれば.その開発の際、プログラマーはビジネスロジックのCodingだけでなく、ログの処理方法、トランザクションのオープンクローズなど、ビジネスロジックに関係のないコードを後に書きます.log.write(class,operate)……
効率的には割引するに違いない.そして、このような重複的な仕事を人力に任せる.非常に問題が発生しやすいです.
 
    今、効率を高めたい.重複作業は機械に任せる.プログラマーはCodingビジネスロジックに専念します.
 
断面向けのプログラミングは,この問題を解決できる.
 
前提:トランザクションの制御は、Bレイヤで発生し、dalレイヤはデータへのアクセスです.ビジネスロジックの統合はB層にある.したがって、B層のメソッドにトランザクションを追加する必要があります.
   
    B層取得実現は、工場取得です.
動的エージェントによるトランザクションのカプセル化:
package com.bjpowernode.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;

/**
 *           
 */
public class TransactionHandler implements InvocationHandler {

	private Object targetObject;
	
	public Object newProxyInstance(Object targetObject){
		this.targetObject=targetObject;
		return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
		
	}
	

	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Connection conn=null;
		Object ret=null;
		try {
			// ThreadLocal   Connection
			conn=ConnectionManager.getConnection();
			
			if(method.getName().startsWith("add") ||
					method.getName().startsWith("del")||
					method.getName().startsWith("modify")){
				
				//      
				ConnectionManager.beginTransaction(conn);
			}
			
			//             
			ret=method.invoke(targetObject, args);
			if (!conn.getAutoCommit()) {
				ConnectionManager.commitTransaction(conn);
			}
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof InvocationTargetException) {
				InvocationTargetException ete=(InvocationTargetException)e;
				throw ete.getTargetException();
			}
			//    
			ConnectionManager.rollbackTransaction(conn);
			throw new ApplicationException("    !");
		}finally{
			ConnectionManager.closeConnection();
		}
		return ret;
	}

}

 
    以上の方法により、B層のオブジェクトを包装するプロセスを行うことができ、  add、del、modifyの先頭の方法.パッケージ上のトランザクションのオープン  ロールバックなどの一連の操作をコミットします.
 
B層実装の取得方法:
/**
	 *         Service    
	 * @param beanId
	 * @return
	 */
	public synchronized Object getServiceObject(Class c){
		if(serviceMap.containsKey(c.getName())){
			return serviceMap.get(c.getName());
		}
		Element beanElt=(Element) doc.selectSingleNode("//service[@id=\""+c.getName()+"\"]");
		String className=beanElt.attributeValue("class");
//		System.out.println(className);
		Object service=null;
		try {
			service=Class.forName(className).newInstance();
			
			//      ,  service      
			TransactionHandler transactionHandler=new TransactionHandler();
			service=transactionHandler.newProxyInstance(service);
			
			//         map 
			serviceMap.put(c.getName(),service);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("  Service  !");
		}
		return service;
	}

    B層オブジェクトのインスタンスを取得するとき、パッケージトランザクションを行います.
 
    上のgetServiceObjectで取得したBレイヤオブジェクトは、削除変更操作を呼び出すとトランザクション制御されます.これにより、プログラマーは開発の過程でビジネスロジックの開発に専念することができます.いつトランザクションを開始する必要があるのか、どのような状況でコミットする必要があるのか、いつロールバックする必要があるのかなど、ビジネスロジックに関係のない一連の操作を考える必要はありません.
 
    これまでは,切断面向けのプログラミングを実現するためにSpring.AOPを用いる必要があったと考えられていた.  学習の深化を通じて、切面向けのプログラミングはどんな技術で実現しても思想であることが分かった.
    オブジェクト向けのプログラミングに切面向けのプログラミングを加える.プログラミングをより楽しく、より効率的にすることができます.