OpenSessionInViewFilter——>TransactionSynchronizationManager

21 篇文章 0 订阅
[java]  view plain copy
  1. public abstract class TransactionSynchronizationManager {  

TransactionSynchronizationManager是管理需要同步的事务资源,也可以管理线程。

下面介绍一下TransactionSynchronizationManager类的一些关键方法:

[java]  view plain copy
  1. public static boolean hasResource(Object key) {  
  2.     Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);  
  3.     Object value = doGetResource(actualKey);  
  4.     return (value != null);  
  5. }  
上面的方法时判断在当前线程中能不能找到session, 判断当前线程是否已经绑定了session,key是sessionFactory对象,一个sessionFactory可以绑定一个session

TransactionSynchronizationUtils工具类的unwrapResourceIfNecessary()方法是解除包装的方法。当一个包装好了的类丢进去则返回的是原始的类,当传进去是一个没包装的类,返回的还是它自己,也就是传进sessionFactory进去,返回的还是sessionFactory。

[java]  view plain copy
  1. public static void bindResource(Object key, Object value) throws IllegalStateException {  
  2.     Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);  
  3.     Assert.notNull(value, "Value must not be null");  
  4.     Map<Object, Object> map = resources.get();  
  5.     // set ThreadLocal Map if none found  
  6.     if (map == null) {  
  7.         map = new HashMap<Object, Object>();  
  8.         resources.set(map);  
  9.     }//得到一个绑定线程的干净Map  
  10.     Object oldValue = map.put(actualKey, value);  
  11.     // Transparently suppress a ResourceHolder that was marked as void...  
  12.     if (oldValue instanceof ResourceHolder && ((ResourceHolder) oldValue).isVoid()) {  
  13.         oldValue = null;  
  14.     }  
  15.            ..............................有些省略  

这里的bindResouce方法是 绑定session到当前线程,这里的resouces是TransactionSynchronizationManager的一个属性如下,是一个ThreadLocal类,里面的泛型T是一个Map传到ThreadLocal里面去。TransactionSynchronizationManager类中还有好几个ThreadLocal,例如ThreadLocal<List<TransactionSynchronization>>,ThreadLocal<String>等

[java]  view plain copy
  1. private static final ThreadLocal<Map<Object, Object>> resources =  
  2.         new NamedThreadLocal<Map<Object, Object>>("Transactional resources");  
[java]  view plain copy
  1. public class ThreadLocal<T> {  
[java]  view plain copy
  1. public class NamedThreadLocal<T> extends ThreadLocal<T> {  
这里ThreadLocal和NamedThreadLocal大概都是一样的,只是 NamedThreadLocal可以通过名字来创建。

我们来到ThreadLocal类里面:

[java]  view plain copy
  1. public void set(T value) {  
  2.     Thread t = Thread.currentThread();  
  3.     ThreadLocalMap map = getMap(t);  
  4.     if (map != null)  
  5.         map.set(this, value);  
  6.     else  
  7.         createMap(t, value);  
  8. }  

[java]  view plain copy
  1. void createMap(Thread t, T firstValue) {  
  2.     t.threadLocals = new ThreadLocalMap(this, firstValue);  
  3. }  

这里有点难理解,在 TransactionSynchronizationManager里面把T也就是map传进来,也就相当是ThreadLocal<Map>,createMap方法将当前线程t和T(Map)传进来,

t.threadLocals=new ThreadLocalMap(this,firstValue); 这里的this就是这个类本身ThreadLocal<Map>,firstValue就是传进来的Map,下表就是一个t.threadLocals,key是类本身,value是T(也就是map),你传进来的T是什么,value就是什么。这里ThreadLocal<Map>也就是ThreadLocal<Map<Object,Object>>

ThreadLocal<Map>Map
ThreadLocal<List>List
ThreadLocal<String>String
ThreadLocal<Boolean>Boolean

这些都放到了threadLocals里面

[java]  view plain copy
  1. public T get() {  
  2.     Thread t = Thread.currentThread();  
  3.     ThreadLocalMap map = getMap(t);  
  4.     if (map != null) {  
  5.         ThreadLocalMap.Entry e = map.getEntry(this);//把类本身传进去当key,得到value(Map<Object,Object>,List<Object>)  
  6.         if (e != null)  
  7.             return (T)e.value;  
  8.     }  
  9.     return setInitialValue();  
  10. }  
[java]  view plain copy
  1. ThreadLocalMap getMap(Thread t) {  
  2.      return t.threadLocals;  
  3.  }  
所以这里可以看到在上面的 TransactionSynchronizationManager中resouces.get()得到的就是传进去的Map,但是现在的这个Map就是已经绑定到线程里面当中去了的Map,

Object oldValue = map.put(actualKey, value);这里则是把SessionFactory和new new SessionHolder(Session)装进Map里面去了,这里也就绑定到线程里面去了。以上这几段代码就是绑定到线程中。

下面是解绑:

[java]  view plain copy
  1. public static Object unbindResource(Object key) throws IllegalStateException {  
  2.     Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);  
  3.     Object value = doUnbindResource(actualKey);  
  4.     if (value == null) {  
  5.         throw new IllegalStateException(  
  6.                 "No value for key [" + actualKey + "] bound to thread [" + Thread.currentThread().getName() + "]");  
  7.     }  
  8.     return value;  
  9. }  
unbindResource方法时将该sessionFactory对应的session从线程里面移除,也就是把t.threadLocals这个Map中移除ThreadLocal<Map>,而这个 ThreadLocal<Map>里面已经存进了SessionFactory和session,移除了ThreadLocal<Map>,也就相当于移除了session
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值