【问题标题】:Can Guice instantiate my classes from class literals?Guice 可以从类文字实例化我的类吗?
【发布时间】:2014-05-12 23:18:57
【问题描述】:

我正在使用 Guice 构建我的应用程序,但我遇到了一种特殊情况。我有一个属性文件,其中包含我的接口和实现类的映射,例如 -

interface = Implclass

我想将 interface.class 绑定到我的 implclass.class

所以当我请求 injector.getInstance(MyInterface.class) Guice 可以返回我的 Impl 类的实例。

这可能吗?

【问题讨论】:

    标签: java guice


    【解决方案1】:

    你可以像这样做一些非常简单的事情:

    class Module extends AbstractModule {
    
      Properties properties;
    
      Module(Properties properties) {
        this.properties = properties;
      }
    
      @Override
      protected void configure() {
        for (Entry<Object, Object> entry: properties.entrySet()) {
          try {
            Class<?> abstractClass = Class.forName((String)entry.getKey());
            Class implementation = Class.forName((String)entry.getValue());
            bind(abstractClass).to(implementation);
          } catch (ClassNotFoundException e) {
            //Handle e
          }
        }
      }
    }
    

    请注意,属性文件需要包含完全限定的类名才能正常工作。我注意到您的问题使用了简短的类名。查看this question 以添加对此的支持。

    Spring 广泛支持基于 XML 的配置,这可能是一个更好的选择,具体取决于您要执行的操作。将绑定保留在代码中是很好的,因为它们可以在重构中幸存下来。

    如果您尝试允许客户端向您的应用程序添加功能,SPI 可能是更好的选择。

    【讨论】:

    • 虽然在与 Guice 团队的 Dhanji 交流后,我意识到实现这一点的最佳方法是使用模块,然后将它们定位在类路径中以自动创建注入器。效果最好。
    【解决方案2】:

    Google says yes:

    public class BillingModule extends AbstractModule {
      @Override 
      protected void configure() {
        bind(TransactionLog.class).to(DatabaseTransactionLog.class);
      }
    }
    

    要获得一个给定类名字符串的类,请使用Class.forName

    【讨论】:

    • 我将类名作为字符串而不是 .class,因为它们是从属性文件加载的。
    猜你喜欢
    • 1970-01-01
    • 2018-10-14
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 2014-09-24
    • 2010-12-07
    • 1970-01-01
    相关资源
    最近更新 更多