java能拦截第三方代码执行吗?

作者站长头像
站长
· 阅读数 12

java的动态代理都是拦截自己写的代码,我想拦截第三方库的代码,比如//这个第三方库的代码x.show();我需要在它执行的前后加上自己的代码。第三方库没有提供钩子。也没有拓展的可能。

回复
1个回答
avatar
test
2024-08-11

结合前面几位的回答,我给出几个我常用的处理办法,由简单到复杂

一、通过类加载器直接覆盖

Java中的类加载器,当前模块Classpath的类优先于其他(Classpath)模块的类,利用这个特点,你可以在你的项目中复制一份第三方的类,包名.类名完全一模一样,但是某个函数或者属性变了(签名没变即可),编译后,你的代码就会覆盖三方代码。

该方式最简单,最有效,最直接。

二、私服或本地jar改源码

如果三方库是开源的,你可以clone下来代码,修改后,打入自己的私服,或者直接lib的形式引入。

三、设计模式

设计模式中有个代理模式和装饰器模式,假如你的调用链非常的短,你能干预调用过程,你可以通过继承、重写、组合的形式,将目标类装饰一层

class TargetPlus extends Target {
    private Target  target;

public TargetPlus (Target target){
    this.target = Target;
}

// .... 其他装饰函数

}

这种适用于修改函数不多,调用链短,访问修饰符开放

四、反射修改对象

java都是对象,如果调用层级过深,调用的某个对象来自类中的某个属性,你可以结合第三步,在即将调用到目标函数时,将某个属性的实例使用反射改了

class A {
    private B b;


    public void run(){
        b.method();
    }
}

void run(){
  A a = new A();
  // 反射将a中b的实例修改为替换的实例。
  a.run();
}

五、有IOC容器/SPI支撑用代理

假如目标三方类是单例,且依靠IOC容器,通过SPI,Spring,dubbo的SPI等创建的对象,你可以在实际调用前,将目标类对象通过动态代理、AOP,装饰,反射等修改,也能达到效果

六、终极方案之Java Agent

如果上面的方案你都不想用,可以使用agent技术,在java -jar启动时,注入自己的agent库,可修改任意代码,非常强大,具体方式自行学习。

七、修改字节码

在代码运行前,通过三方字节码库,将class直接修改,比较复杂。

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容