浅析“代理模式”实现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进行管理啦。

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

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


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

[size=medium] newProxyInstance 中有个参数必须是接口的集合,这个就是原因
[/size]




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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值