使用 GWT 和 Guice,是否可以自动创建接口实例?

发布于 2025-01-05 08:32:55 字数 255 浏览 0 评论 0原文

如果我有一个像

public interface MyInterface{
     public ThingA getThingA();
}

ThingA

public class ThingA{
    public ThingA(){}
}

使用 GWT 和 Guice 的接口,是否可以在不提供具体实现的情况下创建 MyInterface 的默认实例?

If I have an interface like so

public interface MyInterface{
     public ThingA getThingA();
}

where ThingA is

public class ThingA{
    public ThingA(){}
}

With GWT and Guice is it possible to create a default instance of MyInterface without providing a concrete implementation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

放赐 2025-01-12 08:32:55

是的,这是可能的,但不是以常规方式在 JVM 上执行此操作 - 代理类和其他在运行时生成实现的方法不可用,但有 GWT.create 方法,它将查看您的重新绑定规则(在您创建的模块文件中声明,并且您有要包含的 inherits 语句)并提供实现。

使用这些重新绑定规则的最简单方法是用一些更好的实现替换接口或类 - 这使用 标记,您可以指定要替换的内容它与,以及当您更换它时。例如,当您使用 Firefox 时,GWT 会自动将其底层 dom 实现代码替换为 gecko 特定版本:

<replace-with class="com.google.gwt.user.client.impl.DOMImplMozilla">
  <when-type-is class="com.google.gwt.user.client.impl.DOMImpl"/>
  <when-property-is name="user.agent" value="gecko1_8"/>
</replace-with>

这对您没有帮助,但了解一下很有用。

满足这些要求的第二种方法是声明一个 Generator 类来提供您想要的实现。生成器扩展 com.google.gwt.core.ext.Generator,并且(通常)查看传递给它们的类以创建新类型并将其写出,返回其完全限定名称,即然后在调用 GWT.create(SomeClass.class) 的地方使用。

在您的情况下,您可能需要查看接口 MyInterface 中的方法,并执行一些操作,例如为每个方法的返回值调用默认构造函数。因此,要通过生成器获取 MyInterface 的实例,请像这样请求它,并按照接口描述的方式使用它:

MyInterface impl = GWT.create(MyInterface.class);
ThingA a = impl.getThingA();

要声明您的生成器,并且它应该在看到它时替换您的 MyInterface,请在模块中使用类似这样的规则文件(按照惯例,就像 GWT 可编译类放入客户端包中一样,生成器放入重新绑定包中):

<generate-with class="my.package.to.rebind.MyInterfaceGenerator">
  <when-type-is class="my.package.to.client.MyInterface" />
</generate-with>

除此之外,您还需要查看 GWT 代码库中已有的其他生成器(或在核心GWT 团队)。

原始 ImageBundle(现在已被 ClientBundle 取代)相当简单,它实际上如何使用 ClassSourceFileComposerFactory 创建源文件并开始写入 SourceWriter。其中大部分内容可以在 com.google.gwt.user.rebind.ui.ImageBundleGeneratorgenerategenerateImplClass 方法中找到。

GWT 的 RPC 由 com.google.gwt.user.rebind.rpc.ServiceInterfaceProxyGenerator 和 com.google.gwt.user.rebind.rpc.ProxyCreator 生成 - 使用起来有点复杂首先,但确实提供了一些很好的见解,包括使用标记接口来生成(而不是为每个新接口制定新的重新绑定规则,尽管它们做几乎相同的事情)。

Yes, it is possible, but not in the normal way you might do it on a JVM - Proxy classes and other methods of generating an implementation at runtime are not available, but there is the GWT.create method, which will look through your rebind rules (declared in the module files that you create, and that you have inherits statements to include) and provide an implementation.

The easiest way to use these rebind rules is to just replace an interface or a class with some better implementation - this uses the <replace-with /> tags, and you get to specify what to replace it with, and when you replace it. For example, when you are using Firefox, GWT automatically replaces its underlying dom implementation code with a gecko specific version:

<replace-with class="com.google.gwt.user.client.impl.DOMImplMozilla">
  <when-type-is class="com.google.gwt.user.client.impl.DOMImpl"/>
  <when-property-is name="user.agent" value="gecko1_8"/>
</replace-with>

This doesn't help you, but is useful to know.

The second way you can satisfy these is by declaring a Generator class to provide the implementation you want. Generators extend com.google.gwt.core.ext.Generator, and (usually) look at the class passed into them to create a new type and write it out, returning its fully qualified name, which is then used where you called GWT.create(SomeClass.class).

In your case, you would want to look at the methods in the interface MyInterface and do something like call the default constructor for the return value of each. So to get an instance of MyInterface through the generator, ask for it like this, and use it as the interface describes:

MyInterface impl = GWT.create(MyInterface.class);
ThingA a = impl.getThingA();

To declare your generator, and that it should replace your MyInterface where it sees it, use a rule like this in your module file (by convention, just as GWT compilable classes go in a client package, generators go in a rebind package):

<generate-with class="my.package.to.rebind.MyInterfaceGenerator">
  <when-type-is class="my.package.to.client.MyInterface" />
</generate-with>

Beyond that, you'll want to look at what some other generators already in the GWT codebase do (or written outside of the core GWT team).

The original ImageBundle (superseded by ClientBundle now) is fairly simple in how it actually creates its source file with a ClassSourceFileComposerFactory and starts writing to the SourceWriter. The bulk of this can be found in the generate and generateImplClass methods of com.google.gwt.user.rebind.ui.ImageBundleGenerator.

GWT's RPC is generated by com.google.gwt.user.rebind.rpc.ServiceInterfaceProxyGenerator and ``com.google.gwt.user.rebind.rpc.ProxyCreator - this is a little complex to use to start with, but does provide some nice insights, including using a marker interface to generate with (instead of making a new rebind rule for each new interface, though they do nearly the same thing).

国产ˉ祖宗 2025-01-12 08:32:55

这是不可能的,因为这需要创建字节码,但在 javascript 中没有字节码,反射 API 在 GWT 中也不可用。

That cannot be possible because that would require bytecode creation, but in javascript there is no bytecode and reflection API is not available in GWT either.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文