使用Google Guice注入java属性

时间:2012-03-19 15:04:04

标签: java properties guice

我想使用google guice在我的应用程序的所有类中提供属性。我定义了一个模块,用于加载和绑定属性文件 Test.properties

Property1=TEST
Property2=25

package com.test;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

import com.google.inject.AbstractModule;
import com.google.inject.name.Names;

public class TestConfiguration extends AbstractModule {

    @Override
    protected void configure() {
    Properties properties = new Properties();
    try {
        properties.load(new FileReader("Test.properties"));
        Names.bindProperties(binder(), properties);
    } catch (FileNotFoundException e) {
        System.out.println("The configuration file Test.properties can not be found");
    } catch (IOException e) {
        System.out.println("I/O Exception during loading configuration");
    }

    }
}

我正在使用一个主类,我创建一个注入器来注入属性。

package com.test;

import com.google.inject.Guice;
import com.google.inject.Injector;

public class Test {

    public static void main(String[] args) {
    TestConfiguration config = new TestConfiguration();
    Injector injector = Guice.createInjector(config);
    TestImpl test = injector.getInstance(TestImpl.class);
    }
}

package com.test;

import com.google.inject.Inject;
import com.google.inject.name.Named;

public class TestImpl {
    private final String property1;
    private final Integer property2;

        @Inject
        public TestImpl(@Named("Property1") String property1, @Named("Property2") Integer property2) {

        System.out.println("Hello World");
        this.property1 = property1;
        this.property2 = property2;

        System.out.println(property1);
        System.out.println(property2);

        }
     }

现在我的问题。如果我的TestImpl创建了其他类,我还需要注入属性,那些类还需要注入属性,这是正确的方法吗?

  1. 将注入器传递给所有子类,然后使用injector.getInstance(...)创建子类?

  2. 实施新的注射器,如

    TestConfiguration config = new TestConfiguration();
    Injector injector = Guice.createInjector(config);
    TestImpl test = injector.getInstance(TestImpl.class);
    
  3. 在所有嵌套类中?

    1. 是否有其他方法可以在所有类中提供属性?

5 个答案:

答案 0 :(得分:11)

  

将注射器传递给所有子类,然后使用   injector.getInstance(...)来创建子类?

不,通过这样做,你正在击败dependency injection模式的目的,并将你的所有实现与Guice结合起来。除了通过(现在标准化的)注释之外,你的实现根本不应该与guice交互。

  

启用新的注射器,如

TestConfiguration config = new TestConfiguration(); 
Injector injector = Guice.createInjector(config); 
TestImpl test = injector.getInstance(TestImpl.class); 
     

在所有嵌套类中?

不,这更糟糕,因为你最终会有多个注射器,因此多个上下文会妨碍正确使用scopes

理想情况下,您应该只在引导应用程序期间使用注入器。当然,引导它的方式很大程度上取决于应用程序。

  

是否有其他方法可以使所有属性可用   类?

可以像对TestImpl一样注入属性。 如果你想让TestImpl使用,那就说一个也需要一些属性(或其他服务)的服务,让Guice将它注入TestImpl。 Guice正在处理所有的实例化/布线。你只应该告诉Guice“如何继续”,使用活页夹,当Guice无法自己解决这个问题时:

public class TestImpl {
    private final String property1;
    private final Integer property2;
    private final IService service;


        @Inject
        public TestImpl(@Named("Property1") String property1, @Named("Property2") Integer property2, IService service) {
           this.property1 = property1;
           this.property2 = property2;
           this.service= service;
        }
    }
}

答案 1 :(得分:3)

库“Governator”为guice注入提供配置映射功能。方法不同,但可以从属性文件加载。

https://github.com/Netflix/governator/wiki/Configuration-Mapping

答案 2 :(得分:1)

我的方法是guice-config guice-config

答案 3 :(得分:1)

Guice configuration可以为您注入属性或JSON文件到服务的值。

您可以从文件 application.properties 注入您的服务:

@BindConfig(value = "application", syntax = PROPERTIES)
public class Service {

    @InjectConfig
    private int port;

    @InjectConfig
    private String url;

    @InjectConfig
    private Optional<Integer> timeout;
}

您只需安装模块 ConfigurationModule

即可
public class GuiceModule extends AbstractModule {
    @Override
    protected void configure() {
        install(ConfigurationModule.create());
        requestInjection(Service.class);
    }
}

答案 4 :(得分:0)

“现在我的问题。如果我的TestImpl创建了其他类,我还需要注入属性,那些类还需要注入属性,这是正确的方法吗?”

经验法则:避免使用“新”除非绝对必要,否则不要让你的Impl Class“创建其他类”。相反,告诉你的TestImpl,当使用guice创建时,它应该注入所需的实例。