代码写着写着就钻进源码了。

概念

InfrastructureProxy 结构代理

百度查了查,这个类还没有解释。

进去看了一下:

Interface to be implemented by transparent resource proxies that need to be considered as equal to the underlying resource, for example for consistent lookup key comparisons.
Note that this interface does imply such special semantics and does not constitute a general-purpose mixin!

Such wrappers will automatically be unwrapped for key comparisons in TransactionSynchronizationManager.

Only fully transparent proxies, e.g. for redirection or service lookups, are supposed to implement this interface. Proxies that decorate the target object with new behavior, such as AOP proxies, do not qualify here!

中文翻译如下:
透明资源代理要实现的接口,为了被认为等同于底层资源,例如用于一致的查找的关键字比较。
注意,这个接口意味着这样的特殊语义,并不构成一般用途的聚合!

这种包装器将在TransactionSynchronizationManager中自动被拆箱来进行关键字比较。

只有完全透明的代理,例如 对于重定向或服务查找,应该实现此接口。 使用新行为来装饰目标对象的代理(例如AOP代理)不适用于此处!

也就是相当于对象本身等同于所封装的内部对象。

代码:

static Object unwrapResourceIfNecessary(Object resource) {
Assert.notNull(resource, "Resource must not be null");
Object resourceRef = resource;
// unwrap infrastructure proxy
if (resourceRef instanceof InfrastructureProxy) {
resourceRef = ((InfrastructureProxy) resourceRef).getWrappedObject();
}
if (aopAvailable) {
// now unwrap scoped proxy
resourceRef = ScopedProxyUnwrapper.unwrapIfNecessary(resourceRef);
}
return resourceRef;
}

这个方法在TransactionSynchronizationUtils中。

再看看调用者:TransactionSynchronizationManager

public static Object getResource(Object key) {
Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
Object value = doGetResource(actualKey);
if (value != null && logger.isTraceEnabled()) {
logger.trace("Retrieved value [" + value + "] for key [" + actualKey + "] bound to thread [" +
Thread.currentThread().getName() + "]");
}
return value;
} private static Object doGetResource(Object actualKey) {
Map<Object, Object> map = resources.get();
if (map == null) {
return null;
}
Object value = map.get(actualKey);
// Transparently remove ResourceHolder that was marked as void...
if (value instanceof ResourceHolder && ((ResourceHolder) value).isVoid()) {
map.remove(actualKey);
// Remove entire ThreadLocal if empty...
if (map.isEmpty()) {
resources.remove();
}
value = null;
}
return value;
}

resources 就是 NamedThreadLocal,这个不用多说。
如果里面存放的是ResourceHolder并且是Void标记,就透明地移除掉。

调用者是sqlSessionUtils

import static org.springframework.transaction.support.TransactionSynchronizationManager.getResource;


public static SqlSession getSqlSession(SqlSessionFactory sessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) {
....
SqlSessionHolder holder = (SqlSessionHolder) getResource(sessionFactory);
//如果hold已经存在并且不为空。
if (holder != null && holder.isSynchronizedWithTransaction()) {
if (holder.getExecutorType() != executorType) {
throw new TransientDataAccessResourceException("Cannot change the ExecutorType when there is an existing transaction");
}
//直接返回
return holder.getSqlSession();
}
//打开Session
SqlSession session = sessionFactory.openSession(executorType);
.....
if (isSynchronizationActive()) {
Environment environment = sessionFactory.getConfiguration().getEnvironment(); if (environment.getTransactionFactory() instanceof SpringManagedTransactionFactory) { holder = new SqlSessionHolder(session, executorType, exceptionTranslator);
bindResource(sessionFactory, holder);//绑定到TransactionSynchronizationManager
registerSynchronization(new SqlSessionSynchronization(holder, sessionFactory));
holder.setSynchronizedWithTransaction(true);//将连接资源标记为已经同步过
holder.requested();
} else {
//如果不是Spring管理的事务,则看看是不是错误得被搞进Spring了。
if (getResource(environment.getDataSource()) == null) {
if (logger.isDebugEnabled()) {
logger.debug("SqlSession [" + session + "] was not registered for synchronization because DataSource is not transactional");
}
} else {
throw new TransientDataAccessResourceException(
"SqlSessionFactory must be using a SpringManagedTransactionFactory in order to use Spring transaction synchronization");
}
}
} else {
//同步没有激活,不需要注册到同步事务中
if (logger.isDebugEnabled()) {
logger.debug("SqlSession [" + session + "] was not registered for synchronization because synchronization is not active");
}
} return session;
}

最新文章

  1. CSS3 动画实现 animation 和 transition 比较
  2. GitHub和SourceTree入门教程
  3. linux 循环处理文件夹下所有文件脚本
  4. 建立开发板与PC机之间的nfs服务器
  5. c++代码美化
  6. Nutch插件系统
  7. 【NOIP2008】双栈排序
  8. nexcel 读取 excel
  9. 软件工程随堂小作业——随机四则运算(C++)
  10. DataGridView 添加ComboBox
  11. LinkedHashSet的概述和使用
  12. 详解MUI顶部选项卡(tab-top-webview-main)的用法
  13. poj1915
  14. html取消回车刷新提交
  15. VsVim的快捷键
  16. java web各个技术细节总结
  17. windows 下配置 Nginx 常见问题
  18. Jenkins 关闭和重启
  19. Oracle PL/SQL学习之基础篇(2)--例外
  20. [转] etcd 搭建与使用

热门文章

  1. WordPress对接微信小程序遇到的问题
  2. Java 世界的盘古和女娲 —— Zygote
  3. Windows10安装多个版本的PostgreSQL数据库,但是均没有自动注册Windows服务的解决方法
  4. Python基础(十二)
  5. Nginx 配置项优化详解
  6. rpm,yum
  7. Spring Cloud 版本控制
  8. 【Elasticsearch 搜索之路】(一)什么是 Elasticsearch?
  9. k阶斐波那契数列fibonacci第n项求值
  10. Android中Project、Module的区别