【问题标题】:Can someone explain what com.google.inject does?有人可以解释 com.google.inject 的作用吗?
【发布时间】:2013-03-10 06:42:58
【问题描述】:

我看到一个声明了一个类,它的唯一构造函数用@Inject 注释。 而且我没有看到在整个项目中的任何地方都调用了一个构造函数。

那么两个问题:

@Inject 是什么意思? (它有什么作用?为什么构造函数被它注解了?)

如前所述,构造函数永远不会被直接调用,这与它被@Inject注解的事实有关吗?

【问题讨论】:

标签: java annotations inject


【解决方案1】:

Google Guice 是一个依赖注入库,它允许您通过声明对象之间的关系来构造对象。对象的构造是因为它们被要求构造其他对象。您还可以通过配置 Guice 来实现具有不同实现的抽象类或接口,这对于运行或测试代码非常有用。

@Inject 注释构造函数和确定对象需要初始化的方法。还有很多其他的注释决定了 Guice 的工作方式。但是仅仅注释对象是不够的;您还必须使用Guice bindings 配置它们。

这是一个非常简单的示例(来自我的一个应用程序)。我有一个MySQLDataTracker,它需要一个MysqlConnectionPoolDataSource

public class MySQLDataTracker extends ExperimentDataTracker {
    @Inject
    public MySQLDataTracker(MysqlConnectionPoolDataSource ds) {
        ....
    }
}

请注意,MySQLDataTracker 扩展了 ExperimentDataTracker,这是一个可以通过多种方式实现的抽象类。在我的 Guice 绑定中,我声明

bind(ExperimentDataTracker.class).to(MySQLDataTracker.class);

这声明每当我想要一个ExperimentDataTracker 时,都会构造一个MySQLDataTracker。我还需要确保构造它的必要对象可用,所以我声明了一个提供者:

@Provides @Singleton 
MysqlConnectionPoolDataSource getMysqlCPDS() {
    return (some thingy I construct...);            
}

这表示应该只有一个连接池数据源。这也意味着当我尝试获取ExperimentDataTracker 的实例时,Guice 拥有构建它所需的一切。如果我没有上面的,它会抛出一个错误。

ExperimentDataTracker tracker = injector.getInstance(ExperimentDataTracker.class);

然而,它并不止于此。其他的东西依赖于ExperimentDataTracker,所以它又被用来注入其他对象。在我的代码的顶层实际上只有一个对getInstance 的调用,这使得Guice 几乎可以构建所有内容。我不必在任何地方写new 语句。

在看到 Guice 如何减少我为了初始化其他对象而初始化一堆对象的需要之后,我成为了 Guice 的忠实粉丝。基本上我只是要求我想要的对象,然后噗!它出现了。

【讨论】:

  • 那么如果我改变了构造函数的形参,我还需要在哪里改变以确保它被正确调用? (你会建议我在哪里更新对构造函数的“调用”?)
  • 如果您使用 Guice 运行应用程序,如果无法注入某些内容,则会出现错误。这是最好的检查方法。 :) 此外,使用手动构建的模拟对象进行单元测试。
  • 您介意简单解释一下如何在不调用构造函数的情况下构造对象吗?是否有一些配置文件或列出一堆构造函数参数的东西? (对不起,我是新手,我真的很难理解这一点)
  • 是的,我扩展了一点。为了具体回答,Guice 使用反射调用构造函数。但是您应该真正阅读文档以了解它的使用方式。依赖注入非常强大,值得学习,因为它可以为您节省大量工作和重构。
  • 我想我现在理解得更好了。谢谢。
猜你喜欢
  • 2012-05-29
  • 2010-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-14
  • 1970-01-01
  • 1970-01-01
  • 2018-09-05
相关资源
最近更新 更多