问题 Play 2.5.3:使用依赖注入来获取配置值


我正在尝试将Playframework应用程序从2.4迁移到2.5.3,并且我有从中获取值的问题 application.conf 文件:

之前 从中获取值 application.conf 我做的是:

Play.application().configuration().getString("label")

现在 如 Play.application() 不推荐使用,我应该使用依赖注入。基于 框架文档 我使用以下说明:

  1. 定义导入:进口 javax.inject.*; import play.Configuration;
  2. 定义类属性@Inject private Configuration configuration;
  3. 在我的类上使用配置类属性

当我在控制器上按照这些说明操作时 Application.java 它完美地运作:

但是当我尝试在我的项目中的其他类对象上使用它时,依赖注入不起作用,我总是得到一个 NullPointerException

有人可以给我一个关于如何从中获取价值的例子 application.conf 使用依赖注入?

我尝试使用DI的java代码的一部分:

import javax.inject.Inject;
import play.Configuration;
import play.Logger;

public class Zipper {

    @Inject private  Configuration configuration;

    public void unZip(String zipFilePath) {
        Logger.debug("Display : zipFilePath"+zipFilePath);
        Logger.debug("before call parameter from application.conf");
        Logger.debug("configuration.getString = "+configuration.getString("Unzipedfile.path"));
        Logger.debug("aftercall parameter from application.conf");
    }
}

我总是得到一个空指针异常,在行上 configuration.getString("Unzipedfile.path")


10015
2018-05-01 21:42


起源

发布不起作用的代码。 - marcospereira
我按要求更新了。 <br>同样的代码正在我的控制器application.java上工作,但从来没有在我的其他java类上。 - Miguel
您不能注入任何未由DI本身创建或尚未引入Guice上下文的任意类。如果您的类Zipper是由Guice创建的或者是在某处注入的,那么您可以使用上下文注入。看到 stackoverflow.com/a/32896354/1956540 - BatteryAcid
是的,你完全正确,这是我的错误,我在下面提供了一些细节 - Miguel


答案:


我认为您可以像这样初始化配置:

private  Configuration configuration = Play.current().injector().instanceOf(Configuration .class);

所以,你的拉链将是:

import javax.inject.Inject;
import play.Configuration;
import play.Logger;

public class Zipper {

    private  Configuration configuration = Play.current().injector().instanceOf(Configuration .class);

    public void unZip(String zipFilePath) {
        Logger.debug("Display : zipFilePath"+zipFilePath);
        Logger.debug("before call parameter from application.conf");
        Logger.debug("configuration.getString = "+configuration.getString("Unzipedfile.path"));
        Logger.debug("aftercall parameter from application.conf");
    }
}

6
2018-05-25 21:37





尝试使用构造函数注入:

import javax.inject.Inject;
import play.Configuration;
import play.Logger;

public class Zipper {

    private Configuration configuration;

    @Inject
    public Zipper(Configuration config) {
        this.configuration = config;
    }

    public void unZip(String zipFilePath) {
        Logger.debug("Display : zipFilePath"+zipFilePath);
        Logger.debug("before call parameter from application.conf");
        Logger.debug("configuration.getString = "+configuration.getString("Unzipedfile.path"));
        Logger.debug("aftercall parameter from application.conf");
    }
}

我不确定Guice是否能够注射 private 领域。无论如何,构造函数注入是推荐的注入类型。


3
2018-05-02 03:42



我已经看过这种方式,但似乎不符合我的需要。 - Miguel
我已经看过这种方式,但似乎不符合我的需要。因为如果我更新我的构造函数,这意味着在我的调用java类中,我将不得不启动这个新参数,不是吗?有一个类似Zipper zipTest = new Zipper(conf)和conf的东西必须在我的调用java类中启动,我想避免这种情况,在这种情况下注入Zipper类是没用的,不是吗?可能是我错了,你能告诉我如何用你的提议打电话给拉链课吗? - Miguel
而且,正如我所说的注入私有字段正在使用控制器application.java,我只在所有其他java类上有这个问题 - Miguel
你好吗? Zipper 类?你能否编辑一下你的问题,告诉它如何被实例化和使用? - marcospereira
为了你的帮助,我终于找到了我的错误并在下面提供了详细信息 - Miguel


我把答案放在这里,以帮助任何有同样问题的人

我的错误来自于我用来从我的调用类实例化Zipper java类的方式。

感谢Igmar Palsenberg,他给了我答案: https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!topic/play-framework/uLFqTM9_Iy4

我用了 Zipper zipTest = new Zipper(); 实现我的Zipper类,我必须使用 Zipper zipTest = injector.instanceOf(Zipper.class);


3
2018-05-02 21:12



你的班级来电者是考试吗? - marcospereira
nop,只是一个辅助层和拉链类是一个util类,我的理解是,当我使用Zipper zipTest = new Zipper()时,我松散了依赖注入机制。为了保持它,我必须使用injector.instanceOf而不是new - Miguel
所以,你为什么不注射 Zipper 而是进入那个班级? - marcospereira
因为我的目标是将我的代码从2.4更新到2.5.3,并且能够从我需要它的所有类中的application.conf中获取参数。此外,依赖注入对我来说是一种新的模式..在上周日之前未知....现在我的代码正在工作,我必须重构它,以真正适合DI模式。 - Miguel
仅在部分代码中使用依赖注入将使其更难。我的意思是,你将有两种实例化对象的方式。这对我来说听起来更复杂。 - marcospereira


你应该尝试删除 private。 使用:

@Inject Configuration configuration;

代替:

@Inject private  Configuration configuration;

1
2017-10-17 06:53





尝试使用Singleton注释您的类,以便play可以检测您的bean以注入您的资源。


0
2018-05-02 18:17