ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java-Guice:从XML文件设置绑定

2019-10-28 09:13:01  阅读:189  来源: 互联网

标签:dependency-injection guice dynamic-binding xml java


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

我能够加载XML文件并检索所有需要的值(以下是我的XML文件的一个示例),但是我无法使用这些值来绑定(interfaceValue).to(implementationValue);.

到目前为止,我已经尝试过:

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

结果:

>不起作用,因为Guice无法验证实现是否为接口的实现.
>给出错误没有绑定接口的实现.
>可以,但是不需要,因为我必须编辑CustomModule来更改绑定(在这种情况下,如果我希望Bar成为InterfaceFoo的实现).

I’ve looked at this,但是没有太多的成功,因为上面没有太多的文档.我也在这里寻求关于SO的解决方案,但是大多数时候,问题都与属性或注释的使用有关.

有没有一种简单的方法可以在文件中指定接口/实现并将其作为“配置”提供给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>

CustomModule.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);
    }
}

ServiceProvider.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并非真的为此设计.

想法是,通过在类中执行此操作,您将获得在类/ @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

标签:dependency-injection,guice,dynamic-binding,xml,java
来源: https://codeday.me/bug/20191028/1951412.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有