java properties guice

Usar Google Guice para inyectar propiedades de Java



properties (5)

Quiero usar google guice para hacer que las propiedades estén disponibles en todas las clases de mi aplicación. Definí un Módulo que carga y vincula el archivo de propiedades Test.properties .

Property1=TEST Property2=25

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

Estoy usando una clase principal donde creo un inyector para inyectar las propiedades.

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

Ahora mi pregunta. Si mi TestImpl crea otras clases donde también necesito inyectar propiedades, y esas clases también necesitan inyectar propiedades, ¿cuál es la forma correcta de hacerlo?

  1. Pase el inyector a todas las subclases y luego use injector.getInstance (...) para crear las subclases?

  2. Instanciate un nuevo inyector como

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

en todas las clases anidadas?

  1. ¿Hay algún otro enfoque para hacer que las propiedades estén disponibles en todas las clases?

"Ahora mi pregunta. Si mi TestImpl crea otras clases donde también necesito inyectar propiedades, y esas clases también necesitan inyectar propiedades, ¿cuál es la forma correcta de hacer esto?"

Regla de oro: evite el uso de "nuevo" A menos que sea absolutamente necesario, no permita que su Clase Impl "cree otras clases". En cambio, dígale a su TestImpl que cuando se crea con guice, debe obtener las instancias requeridas.




La configuración de biblioteca de Guice puede inyectarle valores desde propiedades o archivos JSON a sus servicios.

Puede inyectar desde el archivo application.properties a su servicio como:

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

Simplemente debe instalar los módulos ConfigurationModule

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


Pase el inyector a todas las subclases y luego use injector.getInstance (...) para crear las subclases?

no, al hacer esto estás derrotando el propósito del patrón de inyección de dependencia y también conectando toda tu implementación con Guice. Sus implementaciones no deberían interactuar en absoluto con guice, excepto a través de las anotaciones (ahora estandarizadas).

Instanciate un nuevo inyector como

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

en todas las clases anidadas?

no, y esto es aún peor porque terminará con inyectores múltiples, por lo tanto, múltiples contextos que evitarán un uso adecuado de los ámbitos .

Idealmente, solo debe usar el inyector durante el arranque de su aplicación. Por supuesto, la forma de arrancarlo dependerá en gran medida de la aplicación.

¿Hay algún otro enfoque para hacer que las propiedades estén disponibles en todas las clases?

Las propiedades se pueden inyectar de la misma manera que lo hizo para TestImpl. Si quiere que TestImpl use, digamos un servicio que también necesita algunas propiedades (u otros servicios), simplemente deje que Guice lo inyecte en TestImpl. Guice se está ocupando de todas las instancias / cableado. Solo debes decirle a Guice "cómo proceder", usando la carpeta, cuando Guice no puede resolver esto por sí mismo:

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