GWT动态加载使用GWT.create()和字符串文本而不是类文本
create()是GWT中的反射等价物, 但它只接受类文本,而不是类名的完全限定字符串。 如何使用GWT.create()动态创建带有字符串的类GWT动态加载使用GWT.create()和字符串文本而不是类文本,gwt,Gwt,create()是GWT中的反射等价物, 但它只接受类文本,而不是类名的完全限定字符串。 如何使用GWT.create()动态创建带有字符串的类 根据许多GWT论坛的帖子,这是不可能的,但是在Rocket GWT()和Gwittir()这样的框架中是如何做到的呢?没有仔细阅读Rocket/Gwittir的代码(如果你想知道他们是如何做到的,你应该这样做,毕竟它是开源的),我只能猜测,它们采用延迟绑定的方式是,在编译时,它们完成对反射的所有调用,并静态生成实现这些调用所需的所有代码。因此,在运行时
根据许多GWT论坛的帖子,这是不可能的,但是在Rocket GWT()和Gwittir()这样的框架中是如何做到的呢?没有仔细阅读Rocket/Gwittir的代码(如果你想知道他们是如何做到的,你应该这样做,毕竟它是开源的),我只能猜测,它们采用延迟绑定的方式是,在编译时,它们完成对反射的所有调用,并静态生成实现这些调用所需的所有代码。因此,在运行时,您不能执行不同的操作。问题到底是什么?我猜您希望将类文本之外的参数传递给生成器 您可能已经知道,传递给GWT.create()的类文本主要是一个选择器,这样GWT就可以选择并执行一个生成器,最终生成一个类。将参数传递给生成器的最简单方法是在接口中使用注释,并将interface.class传递给GWT.create()。当然,请注意,接口/类必须扩展传递到GWT.create()中的类文本
在GWT中,您试图做的是不可能的 虽然GWT在编译时很好地模拟了Java,但运行时当然完全不同。大多数反射都不受支持,并且不可能在运行时生成或动态加载类
我对Gwittir的代码进行了简要的研究,我认为他们在编译时做了“反射”工作。这里:一切皆有可能……尽管可能很难,甚至毫无用处。正如Jan所提到的,你应该使用发电机来实现这一点。基本上,您可以创建接口生成器代码,该代码将获取该接口并在创建时编译,然后返回实例。例如:
//A marker interface
public interface Instantiable {
}
//What you will put in GWT.create
public interface ReflectionService {
public Instantiable newInstance(String className);
}
//gwt.xml, basically when GWT.create finds reflectionservice, use reflection generator
<generate-with class="...ReflectionGenerator" >
<when-type-assignable class="...ReflectionService" />
</generate-with>
//In not a client package
public class ReflectionGenerator extends Generator{
...
}
//A class you may instantiate
public class foo implements Instantiable{
}
//And in this way
ReflectionService service = GWT.create(ReflectionService.class);
service.newInstance("foo");
最后我想,我可以在InstanceFactory中手动完成这项工作。。。
致以最诚挚的问候这是可能的,尽管有点棘手。以下是血淋淋的细节: 如果您只将GWT看作是直接的Java到JS,那么它将不起作用。但是,如果您认为Gnter——特殊类与GWT编译器在编译期间编译并执行,则是可能的。因此,您甚至可以在编译时生成java源代码 我今天有这样的需求——我们的系统处理服务之外的动态资源,以字符串结尾,需要一个类。这是我提出的解决方案-顺便说一句,它在托管IE和Firefox下工作
- 创建一个GWT模块,声明:
- 源路径
- 发电机(应保持在GWT模块源路径包之外)
- 接口替换(它将注入生成的类而不是接口)
- 在该包中,创建一个标记接口(我称之为可构造的)。生成器将查找该标记
- 创建一个基本抽象类来保存该工厂。我这样做是为了简化生成的源代码
- 声明在Application.gwt.xml上继承该模块
- 理解的关键是围绕发电机的概念李>
- 为了方便起见,抽象基类派上了用场李>
- 另外,要理解生成的.js源代码甚至生成的Java源代码中都存在名称强制
- 记住生成器输出java文件
- GWT.create需要一些对.class文件的引用。您的生成器输出可能会这样做,只要它是从您的应用程序中以某种方式引用的(检查application.gwt.xml是否继承了您的模块,这也会用application.gwt.xml声明的生成器替换接口)
- 将GWT.create调用包装在工厂方法/singleton中,也包装在GWT.isClient()下
- 还可以围绕GWT.runAsync包装代码类加载调用,因为它可能需要触发模块加载。这是非常重要的
我希望尽快发布源代码。祝你好运 我能够做我认为您正在尝试做的事情,即加载一个类并将其动态绑定到一个事件;我使用生成器将类动态链接到事件。我不推荐它,但这里有一个例子,如果它有帮助的话: 布莱恩 问题是GWT.create不知道如何为抽象类选择正确的实现 我对新的GWT MVP编码风格也有类似的问题 (见附件) 当我打电话时:
ClientFactory-ClientFactory=GWT.create(ClientFactory.class);
我得到了同样的错误:
延迟绑定结果类型“com.test.mywebapp.client.ClientFactory”不应是抽象的
我所要做的就是在MyWebapp.gwt.xml文件中添加以下行:
<!-- Use ClientFactoryImpl by default -->
<replace-with class="com.test.mywebapp.client.ClientFactoryImpl">
<when-type-is class="com.test.mywebapp.client.ClientFactory"/>
</replace-with>
然后它就像一个符咒一样工作您可以通过在服务器端这样做来避免整个问题。带着服务说 witch接受字符串并返回某种可序列化的超类型。 在服务器端,您可以执行以下操作
return (MySerializableType)Class.forName("className").newInstance();
根据您的情况,这可能不是一个很大的性能瓶颈。我今天遇到了这个问题,并找到了一个解决方案。提问者基本上想要写一个方法,例如:
public <T extends MyInterface> T create(Class<T> clz) {
return (T)GWT.create(clz);
}
代码的样式。最后抛出一个异常,以便在所有情况下都返回一个值
现在调用GWT.create(clz)代码>改为执行以下操作:
private static final Instantiator instantiator = GWT.create(Instantiator.class);
...
return instantiator.create(clz);
还要注意,在GWT模块xml中,您将只为实例化器定义生成器,而不是为MyInterface生成器定义生成器:
<generate-with class="package.rebind.InstantiatorGenerator">
<when-type-assignable class="package.impl.Instantiator" />
</generate-with>
宾果 GXT中的BeanModel实际上可以在编译时围绕生成的代码包装代码,但这仍然需要ClientFact
public interface Instantiator {
public <T extends MyInterface> T create(Class<T> clz);
}
public class InstantiatorGenerator extends Generator {
public String generate(...) {
TypeOracle typeOracle = context.getTypeOracle();
JClassType myTYpe= typeOracle.findType(MyInterface.class.getName());
JClassType[] types = typeOracle.getTypes();
List<JClassType> myInterfaceTypes = Collections.createArrayList();
// Collect all my interface types.
for (JClassType type : types) {
if (type.isInterface() != null && type.isAssignableTo(myType)
&& type.equals(myType) == false) {
myInterfaceTypes.add(type);
}
for (JClassType nestedType : type.getNestedTypes()) {
if (nestedType.isInterface() != null && nestedType.isAssignableTo(myType)
&& nestedType.equals(myTYpe) == false) {
myInterfaceTypes.add(nestedType);
}
}
}
for (JClassType jClassType : myInterfaceTypes) {
MyInterfaceGenerator generator = new MyInterfaceGenerator();
generator.generate(logger, context, jClassType.getQualifiedSourceName());
}
}
// Other instantiator generation code for if () else if () .. constructs as
// explained below.
}
if (clz.getName().equals(MySpecialDerivativeOfMyInterface)) { return (T) new MySpecialDerivativeOfMyInterface_MySpecialImpl();}
private static final Instantiator instantiator = GWT.create(Instantiator.class);
...
return instantiator.create(clz);
<generate-with class="package.rebind.InstantiatorGenerator">
<when-type-assignable class="package.impl.Instantiator" />
</generate-with>