Springboor 打包后添加扩展及依赖注入方案.
背景描述
日常开发中,某些特定情况下 需要对项目保留一定扩展能力,又不能讲源码交互客户,所有有了SPI机制(Service Provider Interface),感兴趣可自行百度,原生的SPI用着比较麻烦,反正就是通过定义接口实现功能的扩展,
本方案主要实现的通过改变jar包指定内容,实现较为方便快捷的动态扩展功能(有丝丝黑客的感觉,用户无感注入一些自定义的内容).
基础理论
命令
java -jar xxx.jar
干了什么,
通过查询资料可知,默认情况下,java检索jar包下META-INF目录内的MANIFEST.MF文件夹,查找Main-Class后的类 执行它的main方法.
将xxx.jar 解压后,可发现Main-Class的多了类 并不是 xxx.yyy.zzz.XyzApplication ,而是
org.springframework.boot.loader.JarLauncher , JarLauncher 即为springboot提供的一个启动器(详情请自行百度),可理解为代理,在项目打包阶段,Springboot的打包插件,将项目工程打包到了 BOOT-INF 文件夹下,对外暴露自己的启动器,通过自己的启动器启动项目,实现一些隐藏功能.
通过阅读 JarLauncher 源码可知, 在 JarLauncher 阶段,获取了项目的所有依赖列表,并加载,不属于列表内的jar包,就算存在也并不会呗加载到JVM中.
由此可通过java的多态直白点就是继承 JarLauncher 重写方法实现扩展jar的注入及一些自定义的功能.
此处有点绕,就不详细的说了,下面来电干活
最简单的扩展方案(不推荐)
通过对解压后文件的查看及对JarLauncher源码的理解 ,
总结出最简单的扩展jar的方式为:
通过压缩工具打开jar包,将想扩展到jar放在BOOT-INF/lib 下, 并且更改 BOOT-INF/classpath.idx 文件内容按照规则手动添加扩展jar包的名称.然后报错jar,即可完成扩展功能.
较为合理的扩展方案(较推荐)
重写***JarLauncher*** 的
@Override
protected ClassLoader createClassLoader(URL[] urls) throws Exception {}
手动将指定目录的jar 添加到urls 中即可,
然后将重写的class 编译后 放到jar包内, 更改 META-INF 目录内的 MANIFEST.MF 为 重写的类, 即可实现 修改一次jar包,扩展任意数量jar的功能.
超级合理的扩展方式(推荐)
想着什么呢.本片就是抛转引玉的,没有什么方案适合适配所有项目,适合自己项目的才是最合适的.
网上也有一些speingboot 插件扩展方案,都大同小异,各有优缺,
注
war包的扩展与jar包类似
不同Springboot版本中
protected ClassLoader createClassLoader(URL[] urls) throws Exception {}
方法返回的 LaunchedURLClassLoader 构造参数有不同.需要根据实际版本灵活适配
向别的博主学习将博客分节,具体参考实现见下一章节,望读者见谅,谢谢大家