首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有没有人有使用cglib MulticastDelegate做类似C#事件的示例代码?

有没有人有使用cglib MulticastDelegate做类似C#事件的示例代码?
EN

Stack Overflow用户
提问于 2010-11-11 07:06:24
回答 1查看 545关注 0票数 2

虽然C#对Java语言中的委托和事件有语言支持,但我们必须要么使用匿名内部类进行绑定,要么使用反射代码http://oatv.com/pub/a/onjava/2003/05/21/delegates.html。在该页面的评论中,有一个关于CGLib多播代理的提示,但是谷歌代码似乎不知道任何用于该类的示例代码。有没有人有一个链接到一个工作的例子,或者有一个在他们的指尖?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-14 01:43:56

我知道这个问题很老了,但也许有一天有人也在想同样的问题。对于普通的C#-like委托,您可能会使用MethodDelegate,而不是MulticastDelegate。假设我们有一个简单的Java POJO bean:

代码语言:javascript
复制
public class SimpleBean {
  private String value;
  public String getValue() {
    return value;
  }
  public void setValue(String value) {
    this.value = value;
  }
}

然后我们可以创建一个插装的(非反射的)委托,如下所示:

代码语言:javascript
复制
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只接受一个方法名作为它的第二个参数。这是MethodDelegate将为您代理的方法。
  • 必须有一个方法,该方法没有为对象定义参数,该对象被作为其第一个参数提供给工厂方法。
  • 第三个参数必须是只有一个参数的接口。MethodDelegate实现了该接口,并可以转换为该接口。调用该方法时,它将对作为第一个参数的对象调用代理方法。

有一些缺点/陷阱:

  • CGlib为每个代理创建一个新类。最终,这将使您的永久生成堆空间变得杂乱。(从长远来看,这可能会导致问题。)
  • 您不能代理接受参数的方法。
  • 如果你的接口接受参数,那么如果不抛出异常(返回值始终为null),方法委托将无法工作。如果您的接口需要另一个返回类型(即使它更通用),您将得到一个IllegalArgumentException。(这很奇怪。)

MulticastDelegate的工作方式略有不同。这一次,我们需要一个bean,它实际上实现了一个只有一个方法的接口:

代码语言:javascript
复制
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 -必须提供单个方法(与前面一样)。此接口必须由添加到此委托代理的任何对象来实现。这可以按如下方式完成:

代码语言:javascript
复制
@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来做一些魔术时,这种魔术会暴露在正常的代码中,这是很尴尬的。此外,你也可以很容易地实现你自己的委托(虽然没有字节码,但我怀疑你是否比手动delegation).
  • When获得了那么多),你的委托返回一个值,你只会收到你添加的最后一个委托的值。所有其他返回值都会丢失(但会在某个时刻由多播委托检索)。

进一步阅读的:我得到了灵感并总结了everything I know about cglib in a blog article

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4149991

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档