代码之家  ›  专栏  ›  技术社区  ›  simbo1905

有没有人有使用cglib multicast委托执行类似C#events的示例代码?

  •  2
  • simbo1905  · 技术社区  · 15 年前

    虽然C#对Java中的委托和事件有语言支持,但我们要么使用匿名内部类进行绑定,要么使用反射代码 http://oatv.com/pub/a/onjava/2003/05/21/delegates.html . 在那个页面上有一些关于CGLib多播委托的提示,但是google代码似乎不知道这个类的任何示例代码。有没有人和一个工作中的例子有联系,其他人也有一个在他们的指尖上?

    1 回复  |  直到 15 年前
        1
  •  1
  •   Rafael Winterhalter    12 年前

    我知道这个问题已经过时了,但也许有一天有人也在想同样的事情。正常情况下 C# -像委托一样,您可能会使用 MethodDelegate ,而不是 MulticastDelegate . 假设我们有一个简单的Java POJO bean:

    public class SimpleBean {
      private String value;
      public String getValue() {
        return value;
      }
      public void setValue(String value) {
        this.value = value;
      }
    }
    

    public static interface BeanDelegate {
      String getValueFromDelegate();
    }
    
    @Test
    public void testMethodDelegate() throws Exception {
      SimpleBean bean = new SimpleBean();
      bean.setValue("Hello world!");
      BeanDelegate delegate = (BeanDelegate) MethodDelegate.create(
          bean, "getValue", BeanDelegate.class);
      assertEquals("Hello world!", delegate.getValueFromDelegate());
    }
    

    关于这个例子有一些需要注意的地方:

    • 工厂法 MethodDelegate#create 方法委托 将为您代理。

    • 一定有办法 没有 为对象定义的参数,该对象作为factory方法的第一个参数。因此 方法委托

    • 第三个参数必须是只有一个参数的接口。这个 实现此接口并可以强制转换为它。当调用该方法时,它将调用第一个参数的对象上的代理方法。

    • CGlib为每个代理创建一个新类。最终,这会浪费您永久的一代堆空间。(从长远来看,这可能会导致问题。)

    • 不能代理接受参数的方法。(真糟糕。)

    • null ). 如果您的接口需要另一个返回类型(即使它更通用),您将得到 IllegalArgumentException . (真奇怪。)

    这个 多播委托

    public class SimpleMulticastBean implements DelegatationProvider {
      private String value;
      public String getValue() {
        return value;
      }
      public void setValue(String value) {
        this.value = value;
      }
    }
    
    public interface DelegatationProvider {
      void setValue(String value);
    }
    

    这次,接口调用 DelegatationProvider 在这个例子中-必须提供一个单一的方法(如前所述)。这个接口 必须

    @Test
    public void testMulticastDelegate() throws Exception {
      MulticastDelegate multicastDelegate = MulticastDelegate.create(
          DelegatationProvider.class);
      SimpleMulticastBean first = new SimpleMulticastBean();
      SimpleMulticastBean second = new SimpleMulticastBean();
      multicastDelegate = multicastDelegate.add(first);
      multicastDelegate = multicastDelegate.add(second);
    
      DelegatationProvider provider = (DelegatationProvider)multicastDelegate;
      provider.setValue("Hello world!");
    
      assertEquals("Hello world!", first.getValue());
      assertEquals("Hello world!", second.getValue());
    }
    

    同样,这种实现也有其缺点:

    • 对象需要实现单个方法接口。这对第三方库来说很糟糕,当您使用CGlib执行某些操作时会很尴尬 魔术 在那里,魔法会暴露在 . 另外,您可以轻松地实现自己的委托(虽然没有字节码,但我怀疑您是否比手动委托赢得了这么多)。

    • 当您的委托返回值时,您将只收到上次添加的委托的值。所有其他返回值都将丢失(但在某个点由多播委托检索)。

    供进一步阅读 :我得到了启发和总结 everything I know about cglib in a blog article