【问题标题】:Play 2.5.3: Using dependency injection to get configuration values玩2.5.3:使用依赖注入获取配置值
【发布时间】:2016-08-26 14:52:43
【问题描述】:

我正在尝试将 Playframework 应用程序从 2.4 迁移到 2.5.3,但我无法从 application.conf 文件中获取值:

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

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

现在因为 Play.application() 已被弃用,我应该使用依赖注入。基于framework documentation,我使用以下说明:

  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")这一行

【问题讨论】:

  • 发布无效的代码。
  • 我已按要求进行了更新。
    相同类型的代码在我的控制器 application.java 上运行,但从未在我的其他 java 类上运行。
  • 你不能注入到任意的类中,这些类不是由 DI 自己创建的或者没有被引入到 Guice 上下文中。如果您的类 Zipper 是由 Guice 创建的或在某处注入的,那么您将拥有要注入的上下文。见stackoverflow.com/a/32896354/1956540
  • 是的,你完全正确,这是我的错误,我在下面写了一些细节

标签: java playframework dependency-injection playframework-2.5


【解决方案1】:

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

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

所以,您的 Zipper 将是:

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");
    }
}

【讨论】:

    【解决方案2】:

    尝试使用构造函数注入:

    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 字段。无论如何,构造函数注入是推荐的注入类型。

    【讨论】:

    • 我见过这种方式,但它似乎不适合我的需要。
    • 我见过这种方式,但它似乎不适合我的需要。因为如果我更新我的构造函数,这意味着在我调用 java 类时,我将不得不启动这个新参数,不是吗?使用 Zipper zipTest = new Zipper(conf) 和 conf 之类的东西必须在我的调用 java 类中启动,我想避免这种情况,在这种情况下,Zipper 类上的注入没有用,不是吗?可能是我错了,你能告诉我如何用你的提议调用拉链类吗?
    • 此外,正如我所说,注入私有字段正在与控制器 application.java 一起使用,我只在所有其他 java 类上遇到这个问题
    • 你是如何使用Zipper类的?您能否将您的问题编辑为如何实例化和使用它?
    • 感谢您的帮助,我终于找到了我的错误并将详细信息放在下面
    【解决方案3】:

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

    我的错误来自我过去从调用类实例化 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);

    【讨论】:

    • 你的类调用者是测试吗?
    • nop,只是一个辅助层,而 zipper 类是一个 util 类,我的理解是,当我使用 Zipper zipTest = new Zipper() 时,我失去了依赖注入机制。为了保留它,我必须使用 injector.instanceOf 而不是 new
    • 那么,你为什么不将Zipper 注入到那个类中呢?
    • 因为我的目标是将我的代码从 2.4 更新到 2.5.3,并且能够从我需要的所有类中访问 application.conf 中的参数。此外,依赖注入对我来说是一种新模式.. 上周日之前未知....现在我的代码正在运行,我必须对其进行重构,以真正适应 DI 模式。
    • 仅在部分代码中使用依赖注入会增加难度。我的意思是,您将有两种实例化对象的方式。这对我来说听起来更复杂。
    【解决方案4】:

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

    @Inject Configuration configuration;
    

    代替:

    @Inject private  Configuration configuration;
    

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 2021-01-08
        • 2016-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-03
        相关资源
        最近更新 更多