使用TransmittableThreadLocal替换Thread Local重新打包spring

 2023-02-03
原文作者:猫仙草 原文地址:https://juejin.cn/post/7042332013692452900

这里是以spring-core模块来说明方法,对于其他的例如spring-bean等模块也适用。


1. 下载 springframework 源码

github地址
看一下自己使用的spring版本,需要注意应该是spring-corespring-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等早期版本,可能会跟上面写的不太一样。
找到NamedThreadLocalNamedInheritableThreadLocal两个类,这两个类都继承自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包即可。