- public abstract class TransactionSynchronizationManager {
TransactionSynchronizationManager是管理需要同步的事务资源,也可以管理线程。
下面介绍一下TransactionSynchronizationManager类的一些关键方法:
- public static boolean hasResource(Object key) {
- Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
- Object value = doGetResource(actualKey);
- return (value != null);
- }
TransactionSynchronizationUtils工具类的unwrapResourceIfNecessary()方法是解除包装的方法。当一个包装好了的类丢进去则返回的是原始的类,当传进去是一个没包装的类,返回的还是它自己,也就是传进sessionFactory进去,返回的还是sessionFactory。
- public static void bindResource(Object key, Object value) throws IllegalStateException {
- Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
- Assert.notNull(value, "Value must not be null");
- Map<Object, Object> map = resources.get();
- // set ThreadLocal Map if none found
- if (map == null) {
- map = new HashMap<Object, Object>();
- resources.set(map);
- }//得到一个绑定线程的干净Map
- Object oldValue = map.put(actualKey, value);
- // Transparently suppress a ResourceHolder that was marked as void...
- if (oldValue instanceof ResourceHolder && ((ResourceHolder) oldValue).isVoid()) {
- oldValue = null;
- }
- ..............................有些省略
这里的bindResouce方法是 绑定session到当前线程,这里的resouces是TransactionSynchronizationManager的一个属性如下,是一个ThreadLocal类,里面的泛型T是一个Map传到ThreadLocal里面去。TransactionSynchronizationManager类中还有好几个ThreadLocal,例如ThreadLocal<List<TransactionSynchronization>>,ThreadLocal<String>等
- private static final ThreadLocal<Map<Object, Object>> resources =
- new NamedThreadLocal<Map<Object, Object>>("Transactional resources");
- public class ThreadLocal<T> {
- public class NamedThreadLocal<T> extends ThreadLocal<T> {
我们来到ThreadLocal类里面:
- public void set(T value) {
- Thread t = Thread.currentThread();
- ThreadLocalMap map = getMap(t);
- if (map != null)
- map.set(this, value);
- else
- createMap(t, value);
- }
- void createMap(Thread t, T firstValue) {
- t.threadLocals = new ThreadLocalMap(this, firstValue);
- }
这里有点难理解,在 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里面
- public T get() {
- Thread t = Thread.currentThread();
- ThreadLocalMap map = getMap(t);
- if (map != null) {
- ThreadLocalMap.Entry e = map.getEntry(this);//把类本身传进去当key,得到value(Map<Object,Object>,List<Object>)
- if (e != null)
- return (T)e.value;
- }
- return setInitialValue();
- }
- ThreadLocalMap getMap(Thread t) {
- return t.threadLocals;
- }
Object oldValue = map.put(actualKey, value);这里则是把SessionFactory和new new SessionHolder(Session)装进Map里面去了,这里也就绑定到线程里面去了。以上这几段代码就是绑定到线程中。
下面是解绑:
- public static Object unbindResource(Object key) throws IllegalStateException {
- Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
- Object value = doUnbindResource(actualKey);
- if (value == null) {
- throw new IllegalStateException(
- "No value for key [" + actualKey + "] bound to thread [" + Thread.currentThread().getName() + "]");
- }
- return value;
- }