记一次项目替换第三方Jar包类的过程
大约 3 分钟
前情提要
这里我们替换了第三方的Jar,并且未修改第三方的jar,这个是如何实现的呢?
替换方法
- 找到你所要重写的方法的所在类,查看其中的路径;
- 在我们的 src 目录下新建一个同包名同类名的类;
- 将jar包中的重写方法所在类的所有代码复制到我们新建的同包名同类名的类中;
- 在我们新建的同包名同类名的类中修改对应的方法中的代码,注意要保持方法中的参数不要发生改变,也不要删除原类中已有的方法,但是可以新增一些方法。
原因分析
Java虚拟机(JVM)寻找Class的顺序:
- Bootstrap classes
属于Java 平台核心的class,比如java.lang.String等.及rt.jar等重要的核心级别的class.这是由JVM Bootstrap class loader来载入的.一般是放置在{java_home}\jre\lib目录下
- Extension classes
基于Java扩展机制,用来扩展Java核心功能模块.一般放置在{Java_home}\jre\lib\ext目录下
- User classes
开发人员或其他第三方开发的Java程序包.通过命令行的-classpath或-cp,或者通过设置CLASSPATH环境变量来引用.JVM通过放置在{java_home}\lib\tools.jar来寻找和调用用户级的class.常用的javac也是通过调用tools.jar来寻找用户指定的路径来编译Java源程序.这样就引出了User class路径搜索的顺序或优先级别的问题.
- 缺省值:调用Java或javawa的当前路径(.),是开发的class所存在的当前目录
- CLASSPATH环境变量设置的路径.如果设置了CLASSPATH,则CLASSPATH的值会覆盖缺省值
- 执行Java的命令行-classpath或-cp的值,如果制定了这两个命令行参数之一,它的值会覆盖环境变量CLASSPATH的值
- -jar 选项:如果通过java -jar 来运行一个可执行的jar包,这当前jar包会覆盖上面所有的值.换句话说,-jar 后面所跟的jar包的优先级别最高,如果指定了-jar选项,所有环境变量和命令行制定的搜索路径都将被忽略.JVM APPClassloader将只会以jar包为搜索范围. 这也是为什么应用程序打包成可执行的jar包后,不管你怎么设置classpath都不能引用到第三方jar包的东西了.
从上面可以知道,我们应用程序的Jar的优先级最高,因此加载用户类的时候会优先加载我们应用程序的类,找不到才会从ClassPath中的第三方Jar中寻找。这样就达到覆盖的作用了。
当然这里还有一个疑问,ClassPath中的第三方Jar里加载类应该优先查找那个Jar呢?