在 Java 中,全部的类默认经过 ClassLoader 加载,而 Java 默认提供了三层的 ClassLoader,并经过双亲委托模型的原则进行加载,其基本模型与加载位置以下线程
Java 中默认的 ClassLoader 都规定了其指定的加载目录,通常也不会经过 JVM 参数来使其加载自定义的目录,因此咱们须要自定义一个 ClassLoader 来加载装有不一样版本的 jar 包的扩展目录,同时为了使运行扩展的 jar 包时,与启动项目实现绝对的隔离,咱们须要保证他们所加载的类不会有相同的 ClassLoader,根据双亲委托模型的原理可知,咱们必须使自定义的 ClassLoader 的 parent 为 null,这样无论是 JRE 自带的 jar 包或一些基础的 Class 都不会委托给 App ClassLoader(固然仅仅是将 Parent 设置为 null 是不够的,后面会说明)。与此同时这些实现了不一样版本的 jar 包,是通过二次开发后的能够独立运行的项目。blog
总的来讲,实现隔离容许指定 jar 包,主要须要作到如下几点:开发
自定义 ClassLoader,使其 Parent = null,避免其使用系统自带的 ClassLoader 加载 Class。
在调用相应版本的方法前,更改当前线程的 ContextClassLoader,避免扩展包的依赖包经过Thread.currentThread().getContextClassLoader()获取到非自定义的 ClassLoader 进行类加载
经过反射获取 Method 时,若是参数为自定义的类型,必定要使用自定义的 ClassLoader 加载参数获取 Class,而后在获取 Method,同时参数也必须转化为使用自定义的 ClassLoade 加载的类型(不一样 ClassLoader 加载的同一个类不相等)get