JAVA-如何修改源码(重写JAR包里的类)

Posted 码农的霸道梦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA-如何修改源码(重写JAR包里的类)相关的知识,希望对你有一定的参考价值。

        今天写代码的时候发现alibaba的druid工具对postgresql数据库的union all语法支持不够完善,具体场景:

select id,name from a

union all

(select id,name from b order by id);

该语法在druid工具中被解析为:

select id,name from a

union all

select id,name from b

order by id;

显而易见,解析后将括号"()"去掉了,去掉之后SQL语义发生了改变,本意是想a表与根据id排序后的b表进行union all,但是解析之后语义为a表与b表union all之后再进行排序,SQL语义发生了巨大变化。那么如何修复呢?目前有三种方法。

第一种:给druid官方提issue(等他们解决,猴年马月了,不适用)

第二种:将使用版本的jar包源码下载下来进行正确修改,编译,上传到私服进行引用(如果遇到版本升级,可能之前修改的就不再生效了)

(建议使用)

第三种:找到要修改的源码的全路径,在项目路径下新建一个相同全路径的类,将源码贴入新建的类中,然后在该类中对相应代码进行正确修改即可,需要注意的一个问题,版本升级时需要注意,该新建的类需要在最新版本的基础之上进行正确修改,防止串版本问题!另外,做好备注,防止后续开发人员不理解相关代码。

最后说一下,项目新建类覆盖源码的原理

1、maven遇到同名类,在pom中先声明的先加载
2、本地类的加载顺序,优先于依赖包中的类

加载顺序实验

maven在遇到同名类时,加载顺序如何?我们做实验测试下。

出现同名类的情况如下,不同包下的MyApi类完全一样:
1、demo应用依赖了api-v1的MyApi类
2、demo应用依赖了api-v2的MyApi类

api-v1版本的代码如下:

api-v2版本的代码如下:

demo调用如下:

package org.example.demo;

import org.example.api.MyApi;

/**
 * @author xxx
 * @date 2022/4/22 11:22 下午
 */
public class App 

    public static void main(String[] args) 
        MyApi myApi = new MyApi();
        myApi.echo();
    


当pom中的引入顺序是下面这种情况,控制台输出:api-v1:

    <dependencies>
        <dependency>
            <groupId>org.example.api</groupId>
            <artifactId>api-v1</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.example.api</groupId>
            <artifactId>api-v2</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

当pom中的引入顺序是下面这种情况,控制台输出:api-v2:

    <dependencies>
        <dependency>
            <groupId>org.example.api</groupId>
            <artifactId>api-v2</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.example.api</groupId>
            <artifactId>api-v1</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

再做一个实验,在demo工程本地也新建一个同名的MyApi类:

package org.example.api;

/**
 * @author xxx
 * @date 2022/4/22 11:25 下午
 */
public class MyApi 

    public void echo() 
        System.out.println("api-demo");
    


目录结构如下:

再次执行main函数,控制台输出:api-demo

才疏学浅,大佬们多指教!

以上是关于JAVA-如何修改源码(重写JAR包里的类)的主要内容,如果未能解决你的问题,请参考以下文章

如何用java代码把一个jar包里的文件替换掉

修改jar包中的配置文件

如何修改jar包里面的.class文件

eclipse jar包里的乱码怎么解决

怎么替换指定jar中的class文件

java命令怎么运行一个包里的多个class文件