java - 如何使用 javassist/CGLib 修改/装饰从第 3 方 API 返回的对象

标签 java proxy javassist cglib

我有一个第 3 方 API 调用,它返回以下对象:

public class A {
  protected void common() {
     System.out.println("common is called in A");
  }

  public void test1() {
    common();
    System.out.println("test1 is called in A");
  }
  public void test2() {
    common();
    System.out.println("test2 is called in A");
  }
}

但我想修改其行为,如以下 ModifiedA 显示:

public class ModifiedA extends A {
  @Override
  protected void common() {
     super.common();
     System.out.println("common is called in ModifiedA");
  }
}

所以我想做的是:

A a = 3rdPartyAPI_call();

//
// Now I'd like to get a ModifiedA which has changed common() behavior.
//

如何使用 javassist/CGLIB 来完成此任务?

一个简单的方法可能是喜欢这样:

public class ModifiedA extends A {
  private A a;
  public ModifiedA(final A a) {
     this.a = a;
  }
  //
  // Override every public method in A
  //

  @Override
  protected void common() {
     super.common();
     System.out.println("common is called in ModifiedA");
  }
}

但是由于 A 的定义来自第 3 方,非常复杂并且可能会发生变化,所以我想使用代理来执行此操作?

感谢您提前发表评论。

最佳答案

您可以使用 CGLib 来实现委托(delegate)者模式,而无需重写所有方法。根据风格,有几种不同的方法可以实现这一点,但这里有一种与您的示例类似的方法。

您可以使用 cglib Enhancer 包装实例:

public static <T> T wrapInstance(final T original) {
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(original.getClass());
    enhancer.setCallback(new MethodInterceptor() {
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            Object returnValue = proxy.invoke(original, args);
            if (method.getName().equals("common")) {
                System.out.println("common is called");
            }
            return returnValue;
        }
    });
    return (T) enhancer.create();
}

关于java - 如何使用 javassist/CGLib 修改/装饰从第 3 方 API 返回的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31606359/

相关文章:

java - Dagger /缺失绑定(bind)。如果没有 @Provides 注释的方法,则无法提供输出器

java - 使用多线程套接字通过mTLS进行Java HTTP代理链接

node.js - 带有缓存的nodejs node-http-proxy设置

c# - 如何编写我自己的代理、匿名器并托管它以在网站在工作中被阻止时提供帮助

java - 无法将字符串转换为本地日期

java - 获取结帐按钮以导航到结帐页面

java - 如何正确使用泛型?

检测 eclipse rcp 应用程序时出现 java.lang.ClassNotFoundException

java - 从多合一 jar 中附加 java 代理

缺少 Javassist 依赖的 jar