【问题标题】:Injecting an object that requires enum in Guice在 Guice 中注入需要枚举的对象
【发布时间】:2021-06-30 13:44:31
【问题描述】:

我有一个要注入的对象,定义为:

    public class EnvironmentModule extends AbstractModule {
    
        @Override
        protected void configure() {
        }
    
        @Provides
        @Singleton
        private String getObject(final Client client) {
            ...
        }
}

Client 是一个枚举,定义为:

@NoArgsConstructor(force = true)
public enum Client {
    private String name;

    Client(final String name) {
        this.name = name;
    }

    public static Client identifyClient(final String clientName) {
   
    }
}

这给了我一个错误- 在客户端中找不到合适的构造函数。类必须有一个(且只有一个)用@Inject 注释的构造函数或一个非私有的零参数构造函数 在 Client.class(Client.java:5) 在 EnvironmentModule.getObject(EnvironmentModule.java:35)

请帮忙。必须做什么。

【问题讨论】:

    标签: java dependency-injection enums constructor guice


    【解决方案1】:

    发生这种情况的原因是因为在你的模块中你没有声明一个Client 的实例被注入到模块的范围内,所以它试图用一个空的构造函数来创建一个实例。这不起作用,因为您的枚举有两个构造函数,而 guice 需要一个空构造函数。解决此问题的方法是创建一个客户单例。我假设你在Client 中省略的代码看起来像

    public enum Client {
    
        //I assume it works like this
        NORMAL_CLIENT("whatever");
    
        private String name;
    
        Client(final String name) {
            this.name = name;
        }
    
        public static Client identifyClient(final String clientName) {
            return Arrays.stream(Client.values())
                .filter(client -> clientName.equals(client.name))
                .findAny()
                //This is dangerous, throw an error if its not found
                .get();
        }
    }
    

    所以我们需要在环境模块中为客户端创建一个单例。这看起来像

    public class EnvironmentModule extends AbstractModule {
        @Override
        protected void configure() {
            super.configure();
        }
    
        @Provides
        @Singleton
        private Client getClient() {
            return Client.identifyClient("whatever");
        }
    
        @Provides
        @Singleton
        private String doWhatever(final Client client) {
            System.out.println("found client " + client);
            return "cool it works";
        }
    }
    

    通过调用模块

    public class Main {
        public static void main(String[] args) {
            final var envInjector = Guice.createInjector(new EnvironmentModule());
            final var client = envInjector.getInstance(Client.class);
            final var doWhateverString = envInjector.getInstance(String.class);
            System.out.println(doWhateverString);
            System.out.println("found instance " + client);
        }
    }
    

    我们可以看到

    found client NORMAL_CLIENT
    cool it works
    found instance NORMAL_CLIENT
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-31
      • 1970-01-01
      • 2013-07-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多