自动委托java类的所有方法

2024-03-05

假设我有一个包含许多公共方法的类:

public class MyClass {

    public void method1() {}
    public void method2() {}
    (...)
    public void methodN() {}

}

现在我想创建一个wrapper类,它将所有方法委托给包装实例(delegate):

public class WrapperClass extends MyClass  {
    private final MyClass delegate;

    public WrapperClass(MyClass delegate) {
        this.delagate = delegate;
    }

    public void method1() { delegate.method1(); }
    public void method2() { delegate.method2(); }
    (...)
    public void methodN() { delegate.methodN(); }

}

现在,如果 MyClass 有很多方法,我需要重写它们中的每一个,这或多或少与“委托”的代码相同。我想知道是否可以做一些魔法来自动调用 Java 中的方法(因此 Wrapper 类需要说“嘿,如果你调用我的方法,只需转到delegate对象并对其调用此方法)。

顺便说一句:我不能使用继承,因为委托不在我的控制之下。我只是从其他地方获取它的实例(另一种情况是如果 MyClass 是最终的)。

注意:我不想要 IDE 生成。我知道我可以在 IntelliJ/Eclipse 的帮助下做到这一点,但我很好奇这是否可以在代码中完成。

有什么建议如何实现这样的目标吗? (注意:我可能可以使用某些脚本语言(例如 php)来完成此操作,我可以使用 php 魔术函数来拦截调用)。


或许动态Proxyjava 可以帮助你。仅当您因此使用接口时它才有效。在这种情况下,我将调用该接口MyInterface并设置默认实现:

public class MyClass implements MyInterface {

    @Override
    public void method1() {
        System.out.println("foo1");
    }

    @Override
    public void method2() {
        System.out.println("foo2");
    }

    @Override
    public void methodN() {
        System.out.println("fooN");
    }

    public static void main(String[] args) {
        MyClass wrapped = new MyClass();
        wrapped.method1();
        wrapped.method2();
        MyInterface wrapper = WrapperClass.wrap(wrapped);
        wrapper.method1();
        wrapper.method2();
    }

}

包装类的实现如下所示:

public class WrapperClass extends MyClass implements MyInterface, InvocationHandler {

    private final MyClass delegate;

    public WrapperClass(MyClass delegate) {
        this.delegate = delegate;
    }

    public static MyInterface wrap(MyClass wrapped) {
        return (MyInterface) Proxy.newProxyInstance(MyClass.class.getClassLoader(), new Class[] { MyInterface.class }, new WrapperClass(wrapped));
    }

    //you may skip this definition, it is only for demonstration
    public void method1() {
        System.out.println("bar");
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Method m = findMethod(this.getClass(), method);
        if (m != null) {
            return m.invoke(this, args);
        }
        m = findMethod(delegate.getClass(), method);
        if (m != null) {
            return m.invoke(delegate, args);
        }
        return null;
    }

    private Method findMethod(Class<?> clazz, Method method) throws Throwable {
        try {
            return clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
        } catch (NoSuchMethodException e) {
            return null;
        }
    }

}

注意这个类:

  • extends MyClass,继承默认实现(任何其他都可以)
  • 实施Invocationhandler,允许代理进行反射
  • 可选地实施MyInterface(满足装饰器模式)

此解决方案允许您重写特殊方法,但委托所有其他方法。这甚至可以与 Wrapper 类的子类一起使用。

注意该方法findMethod尚未捕获特殊情况。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自动委托java类的所有方法 的相关文章

随机推荐

  • 正则表达式:如何匹配不仅仅是数字的字符串

    是否可以编写一个正则表达式来匹配所有不匹配的字符串only包含数字 如果我们有这些字符串 abc a4c 4bc ab4 123 它应该匹配第一个 但不是最后一个 我尝试在 RegexBuddy 中摆弄前瞻之类的东西 但我似乎无法弄清楚 d
  • 如何在关系数据库中建模多语言实体

    如果我们要开发一个多语言应用程序 我们应该将翻译存储在资源文件 or the database 假设我们选择在数据库中进行 是否有一种标准方法来建模多语言实体关系模型 1 一张大翻译表 我们可以将所有翻译存储在一张表中并使用语言中立键为属性
  • Flexbox行:不根据内容增长? [复制]

    这个问题在这里已经有答案了 我有以下结构 我想了解为什么我的行不随其内部内容增长 row border solid red display flex flex direction row cell border solid green fl
  • 在 Maps API 浏览器上设置 HTTP Referrer 会导致 403 错误

    我对 HTTP Referrer 设置如何在 Google Maps API 浏览器密钥上工作感到困惑 我正在构建一个网页 以编程方式从 Google 地图请求图像 主要是 Google 地图街景图像 API 但也从 Javascript
  • spring-boot-starter-web 和 spring-boot-starter-webflux 不能一起工作吗?

    当我开始学习spring webflux 我对这个组件有疑问 我建立了一个简单的项目 使用maven来管理它 我添加了相关的依赖项spring boot starter web and spring boot starter webflux
  • Rufus 调度程序未登录生产环境

    我的 Rails 应用程序在初始化程序中使用 rufus scheduler 启动一个进程 这是初始化程序代码的精简版本 config logger isn t available here so we have to grab it fr
  • React 将 JQuery 代码应用于组件内的元素

    我有一个正在使用 React 的应用程序 我现在遇到一个问题 我正在尝试实施bootstrap 所见即所得 bootstrap3 所见即所得 https github com bootstrap wysiwyg bootstrap3 wys
  • 自动删除SQS队列

    有没有办法完全自动删除 SQS 队列 我有一个解决方案 其中服务器在启动时创建 SQS 并订阅 SNS 主题 然而 可能存在服务器崩溃且无法恢复的情况 在这种情况下 我会用另一台服务器替换该服务器 该服务器会在启动时创建自己的队列 现在之前
  • 对多个区域使用 Matcher.appendReplacement()

    java Matcher appendReplacement 方法 带有appendTail 应该让我将源文本转换为结果文本 同时替换所有出现的模式 伪语言的算法类似于 while Matcher find call Matcher app
  • 用于检查大网址列表中损坏链接的 Python 工具

    我有一个正在生产的搜索引擎 为大约 700 000 个网址提供服务 爬行是使用 Scrapy 完成的 所有蜘蛛程序都使用 DeltaFetch 进行调度 以便获取每日新链接 我面临的困难是处理损坏的链接 我很难找到一种定期扫描和删除损坏链接
  • 是否可以将 HTML/CSS 布局与 GWT 逻辑完全分离?

    我想让我们的 Web 开发人员继续使用纯 HTML 工作 并让开发人员编写 GWT 仅 Java 代码来编写其余的业务逻辑 有可能吗 有人尝试过在 GWT 环境中与 Web 开发人员一起工作吗 如何将 Web 开发人员纳入 GWT 开发流程
  • Typescript 实现接受多种类型输入的通用函数

    出于抽象目的 我需要实现一个接受不同类型输入的函数 type ContentA string type ContentB number type InputA name method a content ContentA type Inpu
  • 如何在 Visual Studio 中切换自动换行?

    Visual Studio NET 是否有办法打开和关闭自动换行 我习惯了 Eclipse 中的这个功能 它允许您右键单击并打开和关闭自动换行 这样当您有向右延伸的长行时 您不必向右和向左移动底部滚动条阅读你的代码 html http we
  • 从字符串在 node.js 中创建一个文本文件并将其作为响应进行流式传输

    我正在使用express js 我有一个字符串 Hello world 我希望用户点击 a href download Download a 用户应该下载包含文本的 Hello txt 而不是打开包含文本的选项卡 我已经四处寻找实现此目的的
  • 如何在 Xcode 4.5 上安装 iOS 4.3 模拟器?

    我通过 App Store 安装了 Xcode 4 5 它支持 iOS 5 1 和 6 0 但不支持 iOS 4 3 也无法在首选项的 下载 选项卡中下载 我尝试从另一台计算机上抓取它并将其放在这台计算机上 因为多米尼克 波拉达描述 htt
  • 如何根据字符数确定文件大小?

    在 Windows 上使用 java 和 jcifs 读取文件 我需要确定文件的大小 其中包含多字节以及 ASCII 字符 我怎样才能有效地实现它或java中的任何现有API Thanks 毫无疑问 要获得确切的字符数 您必须使用正确的编码
  • C# 或 VB 文档注释中的粗体还是斜体?

    有没有办法使用bold or italic里面的文档注释 就像是
  • secItemCopyMatching 返回 nil 数据

    首先 我观看了 WWDC 2013 关于使用钥匙串保护秘密的会议 我想做一个基本的密码存储 看完了整个视频 但在视频的前 10 分钟找到了我需要的东西 这看起来很简单 但我不完全理解数据编码和检索是如何工作的 问题 在 secItemCop
  • 有没有办法跟踪 API 网关限制的调用?

    我一直在使用 CloudWatch 跟踪 API Gateway 和 Lambda 的指标 它显示 Lambda 的受限制的调用 但是有什么方法可以查看 API Gateway 之前限制的调用数量 还没有 但我们计划在不久的将来解决这个问题
  • 自动委托java类的所有方法

    假设我有一个包含许多公共方法的类 public class MyClass public void method1 public void method2 public void methodN 现在我想创建一个wrapper类 它将所有方