我们知道OpenSessionInViewFilter是通过TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));来达到线程绑定的。
抽象类TransactionSynchronizationManager的一些主要属性和方法:
private static final ThreadLocal resources =
new NamedThreadLocal("Transactional resources");//保存了当前线程的session和Transactional信息
private static final ThreadLocal synchronizations =
new NamedThreadLocal("Transaction synchronizations");
private static final ThreadLocal currentTransactionName =
new NamedThreadLocal("Current transaction name");
private static final ThreadLocal currentTransactionReadOnly =
new NamedThreadLocal("Current transaction read-only status");
private static final ThreadLocal currentTransactionIsolationLevel =
new NamedThreadLocal("Current transaction isolation level");
private static final ThreadLocal actualTransactionActive =
new NamedThreadLocal("Actual transaction active");
public static void bindResource(Object key, Object value) throws IllegalStateException {//绑定session到当前线程
Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);//去除包装
Assert.notNull(value, "Value must not be null");
Map map = (Map) resources.get();
// set ThreadLocal Map if none found
if (map == null) {
map = new HashMap();
resources.set(map);
}
if (map.put(actualKey, value) != null) {
throw new IllegalStateException("Already value [" + map.get(actualKey) + "] for key [" +
actualKey + "] bound to thread [" + Thread.currentThread().getName() + "]");
}
if (logger.isTraceEnabled()) {
logger.trace("Bound value [" + value + "] for key [" + actualKey + "] to thread [" +
Thread.currentThread().getName() + "]");
}
}
public static Object unbindResource(Object key) throws IllegalStateException {//解绑当前线程的session
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;
}
public static boolean hasResource(Object key) {//判断当前线程是否已经绑定了session,key是sessionFactory对象,一个sessionFactory可以绑定一个session
Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
Object value = doGetResource(actualKey);
return (value != null);
}
注意:Map map = (Map) resources.get();
public class ThreadLocal<T> :
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
将
ThreadLocal<T>本身作为key,对应的泛型作为value