`
json20080301
  • 浏览: 162798 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

浅析“代理模式”实现spring事务管理

阅读更多
模拟用户调用:
package bean.parterdesign.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		//RealSubject 是接口Subject 的实现类
		RealSubject rs = new RealSubject(); // 在这里指定被代理类
		InvocationHandler ds = new DynamicSubject(rs); // 初始化代理类
		
		//实现类的相关信息
		ClassLoader rsClassLoader = RealSubject.class.getClassLoader(); 
		Class[]  rsInterfaces = RealSubject.class.getInterfaces();
		
		//生成RealSubject 的代理类, 并执行
		Subject subject = (Subject) Proxy.newProxyInstance(	rsClassLoader,rsInterfaces, ds);
		subject.request();
		
		System.out.println("======动态代理类====" + subject.getClass().getName() );
		
		/*// 以下是分解步骤
		 * Class c =  Proxy.getProxyClass(cls.getClassLoader(),cls.getInterfaces()) ;
		 * Constructor ct=c.getConstructor(new Class[]{InvocationHandler.class});
		 * Subject subject =(Subject) ct.newInstance(new Object[]{ds});
		 */
		
		Class c =  Proxy.getProxyClass(rsClassLoader,rsInterfaces) ;
		System.out.println( c.getName() );
		System.out.println("===== 动态代理类实现的接口==" + c.getInterfaces()[0].getName() );
		
	}

}




RealSubject 的代码:
package bean.parterdesign.proxy;

public class RealSubject implements Subject {
	
	public RealSubject()  { 
	
	} 

	//提交数据更新操作
	public void request() { 
		System.out.println("UPDATE DATABASE From real subject."); 
	}
}


DynamicSubject(InvocationHandler接口的实现类) 的代码:
Proxy根据InvocationHandler接口的实现类中的内容生成最后供用户调用的Subject接口

//生成RealSubject 的代理类
Subject subject = (Subject) Proxy.newProxyInstance( rsClassLoader,rsInterfaces, ds);


package bean.parterdesign.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class DynamicSubject implements InvocationHandler {

	private Object sub; // sub 必须是一个接口的实现类
	
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		//为啥要设置自动提交为false ?很多数据库驱动是自动提交的
		System.out.println("设置 Object sub 中的CONNECTION自动提交为false , connect before calling " + method);
		try {
			method.invoke(sub, args);
		} catch (Exception e) {
			System.out.println("发生异常时进行数据回滚 ,  " + method);
		}
		System.out.println("没有异常时,可以提交  after calling " + method);
		return null;
	}
	
	public DynamicSubject() {  

	}

	public DynamicSubject(Object obj) {
		sub = obj;
	}

}


--------------------------------------------------------------------
DynamicSubject 中我们可以模拟数据库操作;实现事务管理;

初级开发者会犯一个错误:直接从SPRING中配置的DATASOURCE中取得CONNECT数据库连接,这样会导致事务失效;
因为你取得的连接的AUTOCOMMIT 是TRUE ;这样事务就没法交给SPRING进行管理啦。

用代理的作用其实就是控制CONNECT数据库连接,通过代理我们可以控制数据库操作的提交和回滚;

另外早期的SPRING事务管理必须是基于接口的,当现在改变啦!为啥必须基于接口?看看这段代码:


Proxy根据InvocationHandler接口的实现类中的内容生成最后供用户调用的Subject接口 ,

newProxyInstance 中有个参数必须是接口的集合,这个就是原因




//生成RealSubject 的代理类 
Subject subject = (Subject) Proxy.newProxyInstance(	rsClassLoader,rsInterfaces, ds);



  • 大小: 26.7 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics