类似于微服务架构那样,但是不使用微服务架构。动态加载第三方jar包,在项目不停止运行的情况下,可随时卸载和添加jar包。
我使用URLClassLoader实现,但是jar包中有关spring的所有注解都使用不了,@Autowired获取不到实体类,@Value获取不到配置文件中的配置
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("file:D:/jar/uin-msggateway-lianlu-0.0.1-SNAPSHOT.jar"),new URL("file:D:/jar/uin-msggateway-ronglian-0.0.1-SNAPSHOT.jar")});
springboot动态加载第三方jar包,可随时卸载和添加jar包
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
17条回答 默认 最新
- lkx444368875 2021-12-14 18:47关注
获得12.00元问题酬金 我这里提供一个实现的思路作为参考吧,想要实现你目前的功能的话:
加载
- 首先将bean工厂先持有起来,作为父类工厂。
- 另外构建一个插件管理器,这个管理器负责动态加载、卸载jar的管理,并持有bean工厂的实例。【相当于一个子工厂】
开始构建jar中的实例,分析实例的元数据【接口、父类等等】
- 1 读取jar中的实例[大鹏cool ]已经给了案例了,在读取到jar对应的class文件的时候,需要
- 实例化
- 属性注入的时候,可以从bean工厂中查找对应的类型set进去
此时,jar中的实例全部持有在插件管理器中。可以缓存起来根据jar名称啥的,方便卸载的时候直接定位到。
在业务代码中进行应用
- 比如你需要根据接口去获取对应的插件实现,你需要从插件管理器中先获取对象,缓存中找不到则再从bean工厂中查找。
不能通过@Autowired去注入。
// 每次获取都是手动去查找,SendService就不能通过注入的方式了。 public void send(){ SendService service = PluginManagerHelper.getBean(SendService.class); service.send(); } // PluginManagerHelper的话,就遍历所有插件去找对应的类型。至于顺序是否唯一的话,根据你的实际情况写逻辑。
尽量保持这个插件管理器中的所有对象不要被外面持有,否则卸载的时候就会出现无法回收的问题。
卸载
所有的jar对象已经被插件管理器所管理起来,卸载的话只需要从缓存中找到匹配的插件对象,删除缓存就行了,等待gc的回收。
当业务需要再次获取SendService
,遍历所有插件的时候发现那个有的插件已经不存在了,所以就匹配不到了。本质上还是将插件的加载作为一个子工厂来维护,不会融入到ioc容器中。这样的好处就是插件jar是有边界的。
另外我想了一下,如果要做到和ioc融入到一起,太复杂了,容器启动的时候所有bean的周期已经确定完毕,你如果这时候要动态来一个bean,不仅要通知已经加载过的bean去看看要不要改变,而且要不断刷新容器,不过也有这样的场景,比如动态更新配置中心,但配置中心的话不会出现要卸载的情况。当然这都是 题外话了。
以上仅为个人思路,希望能帮助到你。
解决 5无用
悬赏问题
- ¥100 求懂行的大ge给小di解答下!
- ¥15 pcl运行在qt msvc2019环境运行效率低于visual studio 2019
- ¥15 MAUI,Zxing扫码,华为手机没反应。可提高悬赏
- ¥15 python运行报错 ModuleNotFoundError: No module named 'torch'
- ¥100 华为手机私有App后台保活
- ¥15 sqlserver中加密的密码字段查询问题
- ¥20 有谁能看看我coe文件到底哪儿有问题吗?
- ¥20 我的这个coe文件到底哪儿出问题了
- ¥15 matlab使用自定义函数时一直报错输入参数过多
- ¥15 设计一个温度闭环控制系统