有人能解释一��� com.google.inject 是做什么的吗?

11
我看到一个类声明其唯一的构造函数带有 @Inject 注释。 但是我在整个项目中都没有看到这个构造函数被调用。
所以有两个问题:
  1. @Inject 是什么意思?(它是做什么的?为什么构造函数要带有它?)
  2. 如上所述,构造函数从未直接被调用,这与它带有 @Inject 注释有关吗?

4
这个类属于Guice库,它本身是一个控制反转框架。 - Perception
1个回答

14

Google Guice 是一个依赖注入库,它允许您通过声明对象之间的关系来简单地构造对象。当需要构造其他对象时才会构建对象。您还可以通过配置 Guice 来实现具有不同实现的抽象类或接口,这使得它非常适用于运行或测试代码。

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

下面是一个非常简单的例子(来自我的一个应用程序)。我有一个需要MysqlConnectionPoolDataSourceMySQLDataTracker

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如何减少我初始化一堆对象以初始化其他对象的需求后,我成为了它的忠实粉丝。基本上我只需要请求我想要的对象,然后它就出现了。


如果我更改构造函数的形式参数,那么我还需要在哪里进行更改以确保它被正确调用?(您建议我在哪里查找以更新对构造函数的“调用”?) - One Two Three
如果您使用Guice运行应用程序,如果某些内容无法注入,您将会收到错误提示。这是检查的最佳方式。 :) 此外,使用手动构建的模拟对象进行单元测试。 - Andrew Mao
你介意简要解释一下如何在不调用构造函数的情况下构建对象吗?是否有某个配置文件或其他东西,可以列出一堆构造函数的参数?(抱歉,我是新手,真的很难理解这个) - One Two Three
是的,我稍微扩展了一下。具体来说,Guice使用反射调用构造函数。但你真的应该阅读文档以了解它的使用方式。依赖注入非常强大且值得学习,因为它可以节省大量工作和重构。 - Andrew Mao
我现在觉得我更好地理解了。谢谢。 - One Two Three

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接