使用TransmittableThreadLocal替换Thre
这里是以spring-core
模块来说明方法,对于其他的例如spring-bean
等模块也适用。
1. 下载 springframework 源码
github地址;
看一下自己使用的spring
版本,需要注意应该是spring-core
、spring-bean
这些spring
模块的版本而不是springboot
的版本,然后把springframework
源码切换到对应的大版本分支上,例如我的是spring-core:5.3.10
,所以我用springframework:5.3.x
。
如果大版本号不匹配,替换掉原版本后可能会引入其他问题。
2. 修改代码
我这里是为了跨线程池的线程共享事务,所以修改的是spring-core
的源码,详见这里:解决@Transactional不能跨线程池共享事务的问题—使用TransmittableThreadLocal。
在spring-core
模块的build.gradle
文件添加TransmittableThreadLocal
依赖:
dependencies {
api("com.alibaba:transmittable-thread-local:2.12.1")
}
这里需要注意的是要符合gradle的语法,gradle升级比较快,语法变动也比较大,不像maven比较稳定。springframework:5.3.x
使用的是gradle:7.0
,如果是springframework:4.3.x
等早期版本,可能会跟上面写的不太一样。
找到NamedThreadLocal
和NamedInheritableThreadLocal
两个类,这两个类都继承自ThreadLocal
,修改为继承自TransmittableThreadLocal
:
public class NamedThreadLocal<T> extends TransmittableThreadLocal<T> {}
public class NamedInheritableThreadLocal<T> extends TransmittableThreadLocal<T> {}
两个类的具体实现不需要修改。
3. 重新打包
在工程的build.gradle
文件添加(版本号根据自己的修改):
allprojects {
group = 'org.springframework'
version = '5.3.11'
}
这样重新打包发布到本地仓库时,就会得到版本号为5.3.11
的包(根据需要自己修改版本号)。
如果你本身会用gradle打包,就按照你自己的方法打包并发布到本地仓库就行;我这边使用的 idea 打包工具,在右侧边栏找到gradle,打开gradle -> spring -> spring-core -> tasks -> publishing -> publishToMavenLocal
,如果是springframework:4.3.x
,是gradle -> spring -> spring-core -> tasks -> other -> install
,其他版本我没有尝试。
如果需要重新打包其他模块,选择对应模块的打包工具就行。
打包成功之后查看本地仓库就能看到新生成的的spring-core
的jar包(本地仓库地址可以在File -> settings -> Build -> Build Tools -> Gradle -> Gradle user home
看到)。
4. 其他工程引入刚才打好的包
使用这个包的其他工程需要在build.gradle
文件加上:
repositories {
mavenLocal()
mavenCentral()
}
mavenLocal()
代表优先使用本地仓库,我一开始忘了这一点,一直只有mavenCentral()
配置,导致 gradle 直接去maven中央仓库拉取,怎么都获取不到自己打的包。
此时按正常方法在build.gradle
文件中引入自己打的spring-core
包即可。