使用Google Guice注入java属性

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

Property1=TEST Property2=25 

包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); 

在所有嵌套类中?

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

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

不,通过这样做,你正在击败dependency injection模式的目的,并将你的所有实现耦合到Guice。 除了通过(现在标准化的)注释之外,您的实现不应与guice进行交互。

实现一个新的注入器

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

在所有嵌套类中?

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

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

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

可以像对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; } } } 

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

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

我的方法是guice-config guice-config

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

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

 @BindConfig(value = "application", syntax = PROPERTIES) public class Service { @InjectConfig private int port; @InjectConfig private String url; @InjectConfig private Optional timeout; } 

您只需安装模块ConfigurationModule即可

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

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

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