gpt4 book ai didi

java - 指南 : Set bindings from an XML file

转载 作者:数据小太阳 更新时间:2023-10-29 02:26:11 24 4
gpt4 key购买 nike

我正在尝试使用 Guice 并在 XML 文件的帮助下进行所有绑定(bind)。在我的模块(假设为“CustomModule”)中,我想加载一个 XML 文件并解析它以设置所有绑定(bind)。

我能够加载 XML 文件并检索所有需要的值(下面是我的 XML 文件的示例),但我无法将这些值用于 bind(interfaceValue).to(implementationValue); .

到目前为止我尝试了什么:

  1. 加载 XML 文件,检索所有值并将它们用作: bind(Class.fromName(Ivalue)).to(Class.fromName(Value));其中 IvalueInterfaceFooValueFoo .
  2. 加载 XML 文件作为属性文件并使用 Names.bindProperties(binder(), properties); .
  3. 手动绑定(bind),这不是我想要的。

结果:

  1. 不起作用,因为 Guice 无法验证实现是否是接口(interface)的实现。
  2. 给出错误 No implementation for interface was bound .
  3. 有效,但不需要,因为我必须编辑我的 CustomModule更改绑定(bind)(如果我希望 BarInterfaceFoo 的实现)。

I've looked at this ,但没有那么成功,因为没有太多的文档。我也在 SO 上寻找解决方案,但大多数时候问题是关于属性或注释的使用。

有没有一种简单的方法可以在文件中指定接口(interface)/实现并将其作为“配置”提供给 Guice?

我的 XML 文件:

<bindings>
<binding>
<interface>interfaces.IReaderService</interface>
<implementation>implementation.MemsReaderService</implementation>
</binding>
<binding>
<interface>interfaces.IReportService </interface>
<implementation>implementation.PdfReportService</implementation>
</binding>
<binding>
<interface>interfaces.ISerializerService </interface>
<implementation>implementation.JsonSerializerService</implementation>
</binding>
<binding>
<interface>interfaces.ILoggerService </interface>
<implementation>implementation.LoggerService</implementation>
</binding>
</bindings>

自定义模块.java:

public class GuiceModule extends AbstractModule{

private HashMap<String, String> classNames = new HashMap<String, String>();

public GuiceModule(){
}

@Override
protected void configure() {
/* === Test 1 [NOK : Module doesn't know if A implements B] */
for(Entry<String, String> entry : classNames.entrySet()){
try {
Class<?> itf = Class.forName(entry.getKey());
Class<?> concrete = Class.forName(entry.getValue());
bind(itf).to(concrete);
} catch (ClassNotFoundException ex) {
Logger.getLogger(GuiceModule.class.getName()).log(Level.SEVERE, null, ex);
}
}
/* === Test 2 [NOK : Not bound] */
try{
File file = new File(getClass().getResource("guiceBindings.xml").toURI());
Properties properties = new Properties();
properties.load(new FileReader(file));
Names.bindProperties(binder(), properties);
} catch (Exception ex) {
Logger.getLogger(GuiceModule.class.getName()).log(Level.SEVERE, null, ex);
}
/* === Test 3 [OK : Manual edition] */
bind(IReaderService.class).to(MemsReaderService.class);
bind(IReportService.class).to(PdfReportService.class);
bind(ISerializerService.class).to(JsonSerializerService.class);
bind(ILoggerService.class).to(LoggerService.class);
}
}

服务提供者.java:

public class ServiceProvider {
// declaration of the services available [FOR NOW]
@Inject IReaderService iReaderService;
@Inject IReportService iReportService;
@Inject ISerializerService iSerializerService;
@Inject ILoggerService iLoggerService;

public ServiceProvider(){
}

// getters of the services injected
public IReaderService getReaderService() {
return iReaderService;
}

public IReportService getReportService() {
return iReportService;
}

public ISerializerService getSerializerService() {
return iSerializerService;
}

public ILoggerService getLoggerService() {
return iLoggerService;
}
}

最佳答案

Guice 并不是为此而设计的。

想法是,通过在类里面进行,您可以获得在类里面进行的所有能力和灵 active /@Provides方法,Provider<T>实现、AOP 等。它确实有 Named.bindProperties ,正如您所观察到的,但这不是您出于上述原因而尝试做的事情。

但是,如果您愿意使用原始类型,您实际上可以执行方法 #1,然后自己检查类。这不是最干净的代码,但请注意,您的问题是 Class<?> 中的通用类型 , 不是 Guice。下面是一个示例,注释掉的伪代码指出您需要进行的更改才能使此代码在生产环境中工作。我想如果你已经走到这一步,你可以自己弄清楚。下面是说明这个想法的代码:

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;

public class DynamicBinding {
static final String interfaceExample = "DynamicBinding$Foo";
static final String implementationExample = "DynamicBinding$FooBar";

public static void main(String... args) throws ClassNotFoundException {
Injector inj = Guice.createInjector(new CustomModule());
Foo blue = inj.getInstance(Foo.class);
blue.doSomething();
}

static class CustomModule extends AbstractModule {

@Override
protected void configure() {
// for (Entry<interface, implementation> : xml file) {
bindFromStrings(interfaceExample, implementationExample);
// }
}

private void bindFromStrings(String interfaceClass, String implClass) {
try {
Class fooClass = Class.forName(interfaceClass);
// I recommend defining a custom exception here with a better message
if (!fooClass.isInterface()) {
throw new Exception("fooClass must be an interface!");
}

Class fooBarClass = Class.forName(implClass);
// I recommend defining a custom exception here with a better message
if (!fooClass.isAssignableFrom(fooBarClass)) {
throw new Exception("classes must be in same inheritance hierarchy");
}

bind(fooClass).to(fooBarClass);
} catch (Exception e) {
// Logger.getLogger().log(blah);
e.printStackTrace();
}
}
}

public static interface Foo {
void doSomething();
}

public static class FooBar implements Foo {
@Override
public void doSomething() {
System.out.println(this.getClass());
}
}
}

输出:

class DynamicBinding$FooBar

关于java - 指南 : Set bindings from an XML file,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30372936/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com