Jar冲突解决二

本文介绍了一种通过自定义ClassLoader改变类加载方式的方法,包括定制加载规则、配置部署、加速访问及热部署等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方案思想
自定义CustomClassLoader,彻底改变classloader的加载方式,自己管理class缓存以及配置文件重定向。根据自定义的加载规则控制3rd jar和配置加载。

CustomClassLoader是自定义的classloader, 修改了java的默认委托规则,任何情况优先加载指定的jar,其父加载器是SystemClassLoader.


相对方案一
可以指定系统中的具体模块按照指定的classloader方式加载,自定义的classloader相对较少,而且配置相对灵活很多。只是对系统的侵入性较方案一高。

 
启动初始化
加载特定配置文件,对于需要按此方式加载的module,也就是配置了bundle模式,初始化对应的CustomClassLoader,如果没有则不加载,和默认方式完全一样。

目录说明
workspace指的module专属的class资源路径,即专属命名空间。
libs指的module专属的必须第三方jar资源路径。
configuration指的module专属的配置文件路径。

 

加载规则
对于加载class
1.CustomClassLoader先从当前自定义缓存加载。(findLoadedClassFromCache)

2.如果缓存内不存在,则从系统class cache加载。(findLoadedClass)
3.如果系统class cache内不存在,则从指定的workspace(本地/远程)目录加载。(findResourceInternal)
4.如果workspace内不存在,则从指定的libs(本地/远程)目录加载。(findResourceInternal)
5.如果libs内不存在,则委托给systemclassloader加载。(parentClassLoader.loader)

对于加载resource
1.CustomerClassLoader先从当前自定义缓存加载。(findLoadedClassFromCache)
2.如果缓存内不存在,则从指定的configuration目录(本地/远程)中加载。(findResourceInternal)
3.如果configuration内不存在,则从指定的libs(本地/远程)目录加载。(findResourceInternal)
4.如果libs内不存在,则委托给systemclassloader加载。(parentClassLoader.loader)

配置部署
当需要调用的有资源冲突模块时,将当前的Thread的contextClassloader修改为CustomClassLoader,并通过反射执行调用逻辑,最后将contextClassloader修改为调用前的ClassLoader.

加速访问
针对加载规则,可以发现,如果出现大量的无法加载的class或者resource,则步骤3内jar文件的IO操作会非常多,如果持续持有jar文件句柄,一则句柄占用,二则jar无法热部署。因此可以用一个设定阀值的LinkedHashMap作为访问libs的前置。
1. 如果一个class经过步骤1-3均无法加载,则将其name放到这个LinkedHashMap。
2. 在步骤3访问libs之前,先判断下LinkedHashMap 是否有这个,如果存在则直接抛ClassNotFoundException.
3. LinkedHashMap达到阀值后会自动清除最先放入的class name.

热部署
java没有自带的文件钩子(也可参考http://flypig.iteye.com/blog/870423实现),可采用对所有modules的workspace,libs,configuration三目录扫描,来查看文件系统是否有变化。
1.如果有变化,则reload相应的module资源,其实就是清除class和resource缓存,还有引用到的static,final等变量,ThreadLocal变量,ExecutorService相关变量等,然后new一个新的CustomClassLoader,原先的等待GC,全部释放相关引用肯定可以GC的。

2.考虑到libs内的jar也需要热部署,因此可采取每个module的lib目录内所有jar运行期间惰性加载,保持一定的时间(计时器)或者一定的加载次数(计数器)后,关闭jar引用,需要加载时再打开即可。不管是计时还是计数,这个统计结算逻辑都可以放到文件扫描的那个后台线程去做。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值