【问题标题】:How to inject instance of my class to another class?如何将我的类的实例注入另一个类?
【发布时间】:2020-03-06 16:15:34
【问题描述】:

我正在使用play framework 2.8.x,我需要将我的配置类注入另一个类,并且我已经编写了用于创建配置的自定义模块。我的模块如下所示:

public class ConfigModule extends AbstractModule {
    private Config config;

    public ConfigModule(Environment environment, Config config) {
        this.config = config;
    }

    @Override
    protected void configure() {
        bindRedisConfig();
    }

    void bindRedisConfig() {
        System.out.println("LOAD");
        RedisConfig redisConfig = new RedisConfig(
                config.getString("configuration.redis.host")
                , config.getInt("configuration.redis.port")
                , config.getString("configuration.redis.password")
                , config.getString("configuration.redis.domain")
        );
        bind(RedisConfig.class).annotatedWith(Names.named(Constant.CONFIG_REDIS)).toInstance(redisConfig);
    }
}

我尝试像这样注入它:

public class ProcessDataStore {
    private final JedisPool jedisPool;
    private final RedisConfig config;

    @Inject
    public ProcessDataStore(RedisConfig config) {
        this.config = config;
    }
}

我的配置类很简单:

@Singleton
public class RedisConfig {
    public final String host;
    public final int port;
    public final String password;
    public final String domain;

    public RedisConfig(String host, int port, String password, String domain) {
        this.host = host;
        this.port = port;
        this.password = password;
        this.domain = domain;
    }
}

但是当我运行我的应用程序时出现异常:

1) Could not find a suitable constructor in config.RedisConfig. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
  at config.RedisConfig.class(RedisConfig.java:17)
  while locating config.RedisConfig
    for the 1st parameter of repository.ProcessDataStore.<init>(ProcessDataStore.java:25)
  while locating repository.ProcessDataStore
    for field at controllers.DashboardController.db(DashboardController.java:19)
  while locating controllers.DashboardController
    for the 5th parameter of router.Routes.<init>(Routes.scala:38)
  at play.api.inject.RoutesProvider$.bindingsFromConfiguration(BuiltinModule.scala:137):
Binding(class router.Routes to self) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$4)

如果我创建没有参数的默认构造函数,我的应用程序不会抛出任何异常但注入的RedisConfig 是空的。 我将我的模块加载到我的应用程序中:

play.modules.enabled += "modules.ConfigModule"

我能做错什么?

【问题讨论】:

    标签: java playframework guice


    【解决方案1】:

    我看到 2 件可疑的事情。

    1) @Singleton 类上的 RedisConfig 注释。它可以让注入器创建和注入RedisConfig类的新实例,而不是redisConfig

    2) 绑定定义包含.annotatedWith(Names.named(Constant.CONFIG_REDIS))。所以ProcessDataStore的constructor参数应该用@Named注解:

     @Inject
     public ProcessDataStore( @Named(Constant.CONFIG_REDIS) RedisConfig config) {...}
    

    【讨论】:

    • 感谢您的帮助!你能给我一些建议,告诉我如何从ModuleConfigRedisConfig 类创建Singleton 吗?
    • 如果我做对了,bind(RedisConfig.class).toInstance(redisConfig); 将满足您的需求。加上 @Singleton 应该从 RedisConfig 中删除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-14
    • 2023-01-25
    • 1970-01-01
    • 2020-04-28
    • 2022-12-05
    • 2014-02-26
    • 2023-01-19
    相关资源
    最近更新 更多