12

我正在检查Google Guice 作为 DI 框架,但我有点困惑:为什么根本没有配置文件?

我找到了关于这个问题的部分解释,但仍然不清楚如何在没有配置文件的情况下设置我的组件角色(或我需要使用开关的任何其他东西)。

任何帮助表示赞赏!

4

6 回答 6

28

配置在代码中而不是配置文件中,这对于许多场景来说都是一个有效的决定。

是的,这意味着如果你想发布一种不同的管道应用程序的方式,你必须重新构建(可能只是模块)——当然,如果你愿意,你仍然可以从命令行参数、属性文件等中获取一些配置值到。

如果您经常需要更改您的应用程序管道并且不想重新部署除单个文件之外的任何内容,那么 Guice 可能不适合您。另一方面,如果您使用 DI 的主要原因是让您的代码更清晰,并且在生产中您将始终使用相同的管道(或足够接近),那么 Guice 是一个不错的选择 - 通常有一些您想要的逻辑在整理管道时使用,以及通常难以以声明方式描述/构造的组件。

不同的 DI 框架有不同的好处和权衡 - 使用最适合您的应用程序的框架。

于 2009-04-19T16:56:18.300 回答
7

如果您愿意,使用配置文件引入 boostrapping 是微不足道的。我们将 Guice 与一个简单的 API 一起使用,该 API 将属性文件加载到真正需要参数化的地方。这可以与@Named 注释等一起使用,当然您可以在模块中使用一些条件(尽管不要过度这样做是个好主意)。

这是我们如何设置部分引导的示例:

public class MetModules extends AbstractModule {

    private static final Logger log = LoggerFactory.getLogger(MetModules.class);

    private final Settings settings;

    public MetModules(Settings settings) {
        this.settings = settings;
    }

    @Override
    protected void configure() {

        // common (stage independent modules) go here
        install(new CommandsModule());
        install(new ServletsModule());
        install(new DataBaseModule(settings));
        install(new JobsModule(settings));

        // any development/ production specific modules
        Stage stage = currentStage();
        if (Stage.DEVELOPMENT.equals(stage)) {
            configureForDevelopment();
        } else { // PRODUCTION
            configureForProduction();
        }
    }

    /**
     * Install modules that will be used in development.
     */
    private void configureForDevelopment() {

        // Mock implementation of email delivery that just logs it got a
        // message rather than trying to send it.
        install(new AbstractModule() {
            @Override
            protected void configure() {
                bind(Delivery.class).toInstance(new Delivery() {

                    public String deliver(MailMessageExchange exchange)
                            throws DeliveryException {
                        log.info("email message: "
                                + exchange.getMessage().getMailMessage()
                                + " to "
                                + Arrays.asList(exchange.getMessage()
                                        .getMailMessage().getTo())
                                + " (not sent)");
                        return "fooMessageId";
                    }
                });
            }
        });

        // local in-memory registry suffices
        install(new LocalServiceRegistryModule());

        // local in memory db implementations of services
        install(new LocalServicesModule());
    }

    /**
     * Install modules that will be used in production.
     */
    private void configureForProduction() {
        // we really only need this (error interception and audit logging)
        // in production
        install(new AopModule());
        install(new ZooKeeperServiceRegistryModule());      }
}

其中 Settings 是读取我们的属性文件等的内容。现在,开发/生产以及特定于部署的特定设置覆盖似乎为我们完成了这项工作,但如果我们显然愿意,我们可以更进一步。

于 2009-12-18T02:27:18.387 回答
5

大多数 DI 配置从一个部署到另一个部署都是相同的,因此它们可以很好地使用代码进行配置,这使得 Guice 的配置非常简洁,您可以获得编译时类型检查、重构工具、代码导航等的好处。

对于那些从部署到另一个更改的东西,例如数据库用户名和密码配置,您可以自己编写所需的代码。编写代码来读取配置文件(可能是属性文件),解析参数,并将它们绑定到您的 Guice 模块中,以便您的应用程序可以访问它们。执行此操作所需的代码不会占用很多代码行。

于 2009-04-19T17:53:49.660 回答
4

Guice 中的很多配置都是隐含的,通过 @Inject 注解。项目中的大量复杂性来自大量的项目工件。Java 文件、Xml 文件、属性文件、数据库、参数.. Guice 试图通过不使用配置文件来消除这种复杂性的一部分。

在编译时重新连接您的应用程序很容易。您很可能只需要编辑您的模块类。对于 Guice 处理的大多数类,您根本不需要配置,而只需要在正确的位置使用 @Inject - 当您有相同接口的两个不同实现时,您只需要配置任何东西 - 或者当您想要从使用 Provider 类的外部库。

于 2009-04-19T17:13:58.010 回答
1

不确定您所说的文件是什么意思,但 Guice 允许您通过 Binder和自定义Providers更改实现。

于 2009-04-19T18:05:58.743 回答
1

我最近创建了以下项目。

http://code.google.com/p/guice-property-injector/

它是 WIP,但允许从基于环境的属性文件运行时注入属性。

于 2010-08-15T08:24:19.477 回答